pycapnp icon indicating copy to clipboard operation
pycapnp copied to clipboard

Order of dict changes the byte representation of a struct

Open olegsinavski opened this issue 6 years ago • 0 comments

Hello,

Thank you very much for the bindings, great stuff! It seems that I found a bug in serialization of simple structures. According to the test below (which fails for me on python 2.7 and 3.6), packed byte representation of the object changes depending on the order of kwargs in new_message function call.

def test_ordering_raw_capnp():
    """Ordering of python dict should not change the hash of the component
    In python2, you have to use special key names to force dict iteration order in CPython
    https://stackoverflow.com/questions/15479928/why-is-the-order-in-dictionaries-and-sets-arbitrary
    In python3, order is determined during creation
    """
    dir = tempfile.mkdtemp()
    filename = os.path.join(dir, 'struct_diff_order.capnp')

    with open(filename, 'w') as f:
        f.write(
            '''
            @0xd5baa3333bc6e2e3;
            struct StructDiffOrder {
              baz @0 :Text;
              bar @1 :Text;
            }
            '''
        )
    schema = capnp.load(filename).StructDiffOrder
    shutil.rmtree(dir)

    bytes = schema.new_message(
        baz='a',
        bar='b').to_bytes_packed()
    different_bytes = schema.new_message(
        bar='b',
        baz='a').to_bytes_packed()

    print(bytes)
    print(different_bytes)
    assert bytes == different_bytes

on python2.7 the last assertion would fail with a prinout:

@	ba
@ab

I assume it shouldn't happen since the scheme clearly specifies the order of fields and should not depend on python bindings order of arguments.

Thank you!

olegsinavski avatar Aug 10 '19 19:08 olegsinavski