Hello community, here is the log from the commit of package python-u-msgpack-python for openSUSE:Factory checked in at 2020-08-01 12:30:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-u-msgpack-python (Old) and /work/SRC/openSUSE:Factory/.python-u-msgpack-python.new.3592 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-u-msgpack-python" Sat Aug 1 12:30:26 2020 rev:9 rq:822417 version:2.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-u-msgpack-python/python-u-msgpack-python.changes 2019-11-04 17:11:50.480609506 +0100 +++ /work/SRC/openSUSE:Factory/.python-u-msgpack-python.new.3592/python-u-msgpack-python.changes 2020-08-01 12:30:34.982423388 +0200 @@ -1,0 +2,7 @@ +Thu Jul 23 12:18:09 UTC 2020 - Marketa Calabkova <mcalabk...@suse.com> + +- update to 2.6.0 + * Add `use_tuple` option to unpacking functions for unpacking MessagePack arrays into tuples. + * Add `ext_serializable()` decorator for registration of application classes with Ext types for automatic packing and unpacking. + +------------------------------------------------------------------- Old: ---- u-msgpack-python-2.5.2.tar.gz New: ---- u-msgpack-python-2.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-u-msgpack-python.spec ++++++ --- /var/tmp/diff_new_pack.eMkvUu/_old 2020-08-01 12:30:36.882425168 +0200 +++ /var/tmp/diff_new_pack.eMkvUu/_new 2020-08-01 12:30:36.886425171 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-u-msgpack-python # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-u-msgpack-python -Version: 2.5.2 +Version: 2.6.0 Release: 0 Summary: A MessagePack serializer and deserializer License: MIT ++++++ u-msgpack-python-2.5.2.tar.gz -> u-msgpack-python-2.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/u-msgpack-python-2.5.2/LICENSE new/u-msgpack-python-2.6.0/LICENSE --- old/u-msgpack-python-2.5.2/LICENSE 2017-08-05 03:25:46.000000000 +0200 +++ new/u-msgpack-python-2.6.0/LICENSE 2020-04-25 10:31:46.000000000 +0200 @@ -1,4 +1,4 @@ - Copyright (c) 2013-2016 vsergeev / Ivan (Vanya) A. Sergeev + Copyright (c) 2013-2020 vsergeev / Ivan (Vanya) A. Sergeev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/u-msgpack-python-2.5.2/PKG-INFO new/u-msgpack-python-2.6.0/PKG-INFO --- old/u-msgpack-python-2.5.2/PKG-INFO 2019-08-15 09:21:16.000000000 +0200 +++ new/u-msgpack-python-2.6.0/PKG-INFO 2020-04-25 10:39:46.034381400 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: u-msgpack-python -Version: 2.5.2 +Version: 2.6.0 Summary: A portable, lightweight MessagePack serializer and deserializer written in pure Python. Home-page: https://github.com/vsergeev/u-msgpack-python Author: vsergeev diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/u-msgpack-python-2.5.2/README.md new/u-msgpack-python-2.6.0/README.md --- old/u-msgpack-python-2.5.2/README.md 2019-03-04 03:10:56.000000000 +0100 +++ new/u-msgpack-python-2.6.0/README.md 2020-04-25 10:31:46.000000000 +0200 @@ -79,6 +79,23 @@ >>> ``` +Serializing and deserializing application-defined types with `ext_serializable()`: +``` python +>>> @umsgpack.ext_serializable(0x50) +... class Point(collections.namedtuple('Point', ['x', 'y'])): +... def packb(self): +... return struct.pack(">ii", self.x, self.y) +... @staticmethod +... def unpackb(data): +... return Point(*struct.unpack(">ii", data)) +... +>>> umsgpack.packb(Point(1, 2)) +b'\xd7P\x00\x00\x00\x01\x00\x00\x00\x02' +>>> umsgpack.unpackb(_) +Point(x=1, y=2) +>>> +``` + Serializing and deserializing application-defined types with Ext handlers: ``` python >>> umsgpack.packb([complex(1,2), decimal.Decimal("0.31")], @@ -113,6 +130,45 @@ >>> ``` +## Ext Serializable + +The `ext_serializable()` decorator registers application classes for automatic +packing and unpacking with the specified Ext type. The decorator accepts the +Ext type code as an argument. The application class should implement a +`packb()` method that returns serialized bytes, and an `unpackb()` class method +or static method that accepts serialized bytes and returns an instance of the +application class. + +Example for registering, packing, and unpacking a custom class with Ext type +code 0x10: + +``` python +@umsgpack.ext_serializable(0x10) +class Point(object): + def __init__(self, x, y, z): + self.x = x + self.y = y + self.z = z + + def __str__(self): + return "Point({}, {}, {})".format(self.x, self.y, self.z) + + def packb(self): + return struct.pack(">iii", self.x, self.y, self.z) + + @staticmethod + def unpackb(data): + return Point(*struct.unpack(">iii", data)) + +# Pack +obj = Point(1,2,3) +data = umsgpack.packb(obj) + +# Unpack +obj = umsgpack.unpackb(data) +print(obj) # -> Point(1, 2, 3) +``` + ## Ext Handlers The packing functions accept an optional `ext_handlers` dictionary that maps @@ -225,6 +281,18 @@ >>> ``` +## Tuples + +The unpacking functions provide a `use_tuple` option to unpack MessagePack arrays into tuples, rather than lists. + +``` python +>>> umsgpack.unpackb(b'\x93\xa1a\xc3\x92\x01\x92\x02\x03') +['a', True, [1, [2, 3]]] +>>> umsgpack.unpackb(b'\x93\xa1a\xc3\x92\x01\x92\x02\x03', use_tuple=True) +('a', True, (1, (2, 3))) +>>> +``` + ### Invalid UTF-8 Strings The unpacking functions provide an `allow_invalid_utf8` option to unpack MessagePack strings with invalid UTF-8 into the `umsgpack.InvalidString` type, instead of throwing an exception. The `umsgpack.InvalidString` type is a subclass of `bytes`, and can be used like any other `bytes` object. @@ -289,6 +357,19 @@ >>> ``` +* `NotImplementedError`: Ext serializable class is missing implementation of `packb()`. + + ``` python + >>> @umsgpack.ext_serializable(0x50) + ... class Point(collections.namedtuple('Point', ['x', 'y'])): + ... pass + ... + >>> umsgpack.packb(Point(1, 2)) + ... + NotImplementedError: Ext serializable class <class '__main__.Point'> is missing implementation of packb() + >>> + ``` + ### Unpacking Exceptions If a non-byte-string argument is passed to `umsgpack.unpackb()`, it will raise a `TypeError` exception. If an error occurs during unpacking, umsgpack will raise an exception derived from `umsgpack.UnpackException`. All possible unpacking exceptions are described below. @@ -387,6 +468,19 @@ >>> ``` +* `NotImplementedError`: Ext serializable class is missing implementation of `unpackb()`. + + ``` python + >>> @umsgpack.ext_serializable(0x50) + ... class Point(collections.namedtuple('Point', ['x', 'y'])): + ... pass + ... + >>> umsgpack.unpackb(b'\xd7\x50\x00\x00\x00\x01\x00\x00\x00\x02') + ... + NotImplementedError: Ext serializable class <class '__main__.Point'> is missing implementation of unpackb() + >>> + ``` + ## Behavior Notes * Python 2 @@ -402,6 +496,7 @@ * The Python `datetime.datetime` type is packed into, and unpacked from, the msgpack `timestamp` format * Note that this Python type only supports microsecond resolution, while the msgpack `timestamp` format supports nanosecond resolution. Timestamps with finer than microsecond resolution will lose precision during unpacking. Users may override the packing and unpacking of the msgpack `timestamp` format with a custom type for alternate behavior. * Both naive and aware timestamp are supported. Naive timestamps are packed as if they are in the UTC timezone. Timestamps are always unpacked as aware `datetime.datetime` objects in the UTC timezone. +* Ext type handlers specified in the optional `ext_handlers` dictionary will override `ext_serializable()` classes during packing and unpacking ## Testing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/u-msgpack-python-2.5.2/setup.py new/u-msgpack-python-2.6.0/setup.py --- old/u-msgpack-python-2.5.2/setup.py 2019-08-15 09:18:51.000000000 +0200 +++ new/u-msgpack-python-2.6.0/setup.py 2020-04-25 10:31:46.000000000 +0200 @@ -5,7 +5,7 @@ setup( name='u-msgpack-python', - version='2.5.2', + version='2.6.0', description='A portable, lightweight MessagePack serializer and deserializer written in pure Python.', author='vsergeev', author_email='v...@sergeev.io', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/u-msgpack-python-2.5.2/test_umsgpack.py new/u-msgpack-python-2.6.0/test_umsgpack.py --- old/u-msgpack-python-2.5.2/test_umsgpack.py 2019-08-15 09:18:40.000000000 +0200 +++ new/u-msgpack-python-2.6.0/test_umsgpack.py 2020-04-25 10:21:55.000000000 +0200 @@ -319,6 +319,12 @@ ["float precision double", 2.5, b"\xcb\x40\x04\x00\x00\x00\x00\x00\x00"], ] +tuple_test_vectors = [ + ["nested array", [0x01, [b"\x80", [[u"a", u"b", u"c"], True]]], + b"\x92\x01\x92\xc4\x01\x80\x92\x93\xa1a\xa1b\xa1c\xc3", + (0x01, (b"\x80", ((u"a", u"b", u"c"), True)))], +] + naive_timestamp_test_vectors = [ ["32-bit timestamp (naive)", datetime.datetime(2000, 1, 1, 10, 5, 2, 0, umsgpack._utc_tzinfo), b"\xd6\xff\x38\x6d\xd1\x4e", @@ -377,6 +383,7 @@ "DuplicateKeyException", "KeyNotPrimitiveException", "KeyDuplicateException", + "ext_serializable", "pack", "packb", "unpack", @@ -518,6 +525,19 @@ self.assertTrue(isinstance(unpacked, OrderedDict)) self.assertEqual(unpacked, obj) + def test_unpack_tuple(self): + # Use tuple test vector + (_, obj, data, obj_tuple) = tuple_test_vectors[0] + + # Unpack with default options (list) + self.assertEqual(umsgpack.unpackb(data), obj) + + # Unpack with use_tuple=False (list) + self.assertEqual(umsgpack.unpackb(data, use_tuple=False), obj) + + # Unpack with use_tuple=True (tuple) + self.assertEqual(umsgpack.unpackb(data, use_tuple=True), obj_tuple) + def test_ext_exceptions(self): with self.assertRaises(TypeError): _ = umsgpack.Ext(5.0, b"") @@ -590,6 +610,68 @@ unpacked = umsgpack.unpackb(data, ext_handlers=override_ext_handlers) self.assertEqual(unpacked, obj) + def test_ext_serializable(self): + # Register test class + @umsgpack.ext_serializable(0x20) + class CustomComplex: + def __init__(self, real, imag): + self.real = real + self.imag = imag + + def __eq__(self, other): + return self.real == other.real and self.imag == other.imag + + def packb(self): + return struct.pack("<II", self.real, self.imag) + + @classmethod + def unpackb(cls, data): + return cls(*struct.unpack("<II", data)) + + obj, data = CustomComplex(123, 456), b"\xd7\x20\x7b\x00\x00\x00\xc8\x01\x00\x00" + + # Test pack + packed = umsgpack.packb(obj) + self.assertEqual(packed, data) + + # Test unpack + unpacked = umsgpack.unpackb(packed) + self.assertTrue(isinstance(unpacked, CustomComplex)) + self.assertEqual(unpacked, obj) + + _, obj, data = ext_handlers_test_vectors[0] + + # Test pack priority of ext_handlers over ext_serializable() + packed = umsgpack.packb(obj, ext_handlers=ext_handlers) + self.assertEqual(packed, data) + + # Test unpack priority of ext_handlers over ext_serializable() + unpacked = umsgpack.unpackb(data, ext_handlers=ext_handlers) + self.assertTrue(isinstance(unpacked, complex)) + self.assertEqual(unpacked, obj) + + # Test registration collision + with self.assertRaises(ValueError): + @umsgpack.ext_serializable(0x20) + class DummyClass: + pass + + # Register class with missing packb() and unpackb() + @umsgpack.ext_serializable(0x21) + class IncompleteClass: + pass + + # Test unimplemented packb() + with self.assertRaises(NotImplementedError): + umsgpack.packb(IncompleteClass()) + + # Test unimplemented unpackb() + with self.assertRaises(NotImplementedError): + umsgpack.unpackb(b"\xd4\x21\x00") + + # Unregister Ext serializable classes for future tests + umsgpack._ext_classes = {} + def test_streaming_writer(self): # Try first composite test vector (_, obj, data) = composite_test_vectors[0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/u-msgpack-python-2.5.2/u_msgpack_python.egg-info/PKG-INFO new/u-msgpack-python-2.6.0/u_msgpack_python.egg-info/PKG-INFO --- old/u-msgpack-python-2.5.2/u_msgpack_python.egg-info/PKG-INFO 2019-08-15 09:21:15.000000000 +0200 +++ new/u-msgpack-python-2.6.0/u_msgpack_python.egg-info/PKG-INFO 2020-04-25 10:39:45.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: u-msgpack-python -Version: 2.5.2 +Version: 2.6.0 Summary: A portable, lightweight MessagePack serializer and deserializer written in pure Python. Home-page: https://github.com/vsergeev/u-msgpack-python Author: vsergeev diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/u-msgpack-python-2.5.2/umsgpack.py new/u-msgpack-python-2.6.0/umsgpack.py --- old/u-msgpack-python-2.5.2/umsgpack.py 2019-08-15 09:18:51.000000000 +0200 +++ new/u-msgpack-python-2.6.0/umsgpack.py 2020-04-25 10:31:46.000000000 +0200 @@ -1,4 +1,4 @@ -# u-msgpack-python v2.5.2 - v at sergeev.io +# u-msgpack-python v2.6.0 - v at sergeev.io # https://github.com/vsergeev/u-msgpack-python # # u-msgpack-python is a lightweight MessagePack serializer and deserializer @@ -10,7 +10,7 @@ # # MIT License # -# Copyright (c) 2013-2016 vsergeev / Ivan (Vanya) A. Sergeev +# Copyright (c) 2013-2020 vsergeev / Ivan (Vanya) A. Sergeev # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -31,7 +31,7 @@ # THE SOFTWARE. # """ -u-msgpack-python v2.5.2 - v at sergeev.io +u-msgpack-python v2.6.0 - v at sergeev.io https://github.com/vsergeev/u-msgpack-python u-msgpack-python is a lightweight MessagePack serializer and deserializer @@ -54,10 +54,10 @@ else: from collections import Hashable -__version__ = "2.5.2" +__version__ = "2.6.0" "Module version string" -version = (2, 5, 2) +version = (2, 6, 0) "Module version tuple" @@ -104,9 +104,8 @@ """ Compare this Ext object with another for equality. """ - return (isinstance(other, self.__class__) and - self.type == other.type and - self.data == other.data) + return isinstance(other, self.__class__) \ + and self.type == other.type and self.data == other.data def __ne__(self, other): """ @@ -135,7 +134,43 @@ class InvalidString(bytes): """Subclass of bytes to hold invalid UTF-8 strings.""" - pass + + +############################################################################## +# Ext Serializable Decorator +############################################################################## + +_ext_classes = {} + + +def ext_serializable(ext_type): + """ + Return a decorator to register a class for automatic packing and unpacking + with the specified Ext type code. The application class should implement a + `packb()` method that returns serialized bytes, and an `unpackb()` class + method or static method that accepts serialized bytes and returns an + instance of the application class. + + Args: + ext_type: application-defined Ext type code + + Raises: + ValueError: + Ext type or class already registered. + """ + def wrapper(cls): + if ext_type in _ext_classes: + raise ValueError("Ext type 0x{:02x} already registered with class {:s}".format(ext_type, repr(_ext_classes[ext_type]))) + elif cls in _ext_classes: + raise ValueError("Class {:s} already registered with Ext type 0x{:02x}".format(repr(cls), ext_type)) + + _ext_classes[ext_type] = cls + _ext_classes[cls] = ext_type + + return cls + + return wrapper + ############################################################################## # Exceptions @@ -145,39 +180,32 @@ # Base Exception classes class PackException(Exception): "Base class for exceptions encountered during packing." - pass class UnpackException(Exception): "Base class for exceptions encountered during unpacking." - pass # Packing error class UnsupportedTypeException(PackException): "Object type not supported for packing." - pass # Unpacking error class InsufficientDataException(UnpackException): "Insufficient data to unpack the serialized object." - pass class InvalidStringException(UnpackException): "Invalid UTF-8 string encountered during unpacking." - pass class UnsupportedTimestampException(UnpackException): "Unsupported timestamp format encountered during unpacking." - pass class ReservedCodeException(UnpackException): "Reserved code encountered during unpacking." - pass class UnhashableKeyException(UnpackException): @@ -185,12 +213,10 @@ Unhashable key encountered during map unpacking. The serialized map cannot be deserialized into a Python dictionary. """ - pass class DuplicateKeyException(UnpackException): "Duplicate key encountered during map unpacking." - pass # Backwards compatibility @@ -340,14 +366,11 @@ elif obj_len == 16: fp.write(b"\xd8" + struct.pack("B", obj.type & 0xff) + obj.data) elif obj_len < 2**8: - fp.write(b"\xc7" + - struct.pack("BB", obj_len, obj.type & 0xff) + obj.data) + fp.write(b"\xc7" + struct.pack("BB", obj_len, obj.type & 0xff) + obj.data) elif obj_len < 2**16: - fp.write(b"\xc8" + - struct.pack(">HB", obj_len, obj.type & 0xff) + obj.data) + fp.write(b"\xc8" + struct.pack(">HB", obj_len, obj.type & 0xff) + obj.data) elif obj_len < 2**32: - fp.write(b"\xc9" + - struct.pack(">IB", obj_len, obj.type & 0xff) + obj.data) + fp.write(b"\xc9" + struct.pack(">IB", obj_len, obj.type & 0xff) + obj.data) else: raise UnsupportedTypeException("huge ext data") @@ -366,18 +389,14 @@ if microseconds == 0 and 0 <= seconds <= 2**32 - 1: # 32-bit timestamp - fp.write(b"\xd6\xff" + - struct.pack(">I", seconds)) + fp.write(b"\xd6\xff" + struct.pack(">I", seconds)) elif 0 <= seconds <= 2**34 - 1: # 64-bit timestamp value = ((microseconds * 1000) << 34) | seconds - fp.write(b"\xd7\xff" + - struct.pack(">Q", value)) + fp.write(b"\xd7\xff" + struct.pack(">Q", value)) elif -2**63 <= abs(seconds) <= 2**63 - 1: # 96-bit timestamp - fp.write(b"\xc7\x0c\xff" + - struct.pack(">I", microseconds * 1000) + - struct.pack(">q", seconds)) + fp.write(b"\xc7\x0c\xff" + struct.pack(">Iq", microseconds * 1000, seconds)) else: raise UnsupportedTypeException("huge timestamp") @@ -453,6 +472,11 @@ _pack_nil(obj, fp, options) elif ext_handlers and obj.__class__ in ext_handlers: _pack_ext(ext_handlers[obj.__class__](obj), fp, options) + elif obj.__class__ in _ext_classes: + try: + _pack_ext(Ext(_ext_classes[obj.__class__], obj.packb()), fp, options) + except AttributeError: + raise NotImplementedError("Ext serializable class {:s} is missing implementation of packb()".format(repr(obj.__class__))) elif isinstance(obj, bool): _pack_boolean(obj, fp, options) elif isinstance(obj, (int, long)): @@ -525,6 +549,11 @@ _pack_nil(obj, fp, options) elif ext_handlers and obj.__class__ in ext_handlers: _pack_ext(ext_handlers[obj.__class__](obj), fp, options) + elif obj.__class__ in _ext_classes: + try: + _pack_ext(Ext(_ext_classes[obj.__class__], obj.packb()), fp, options) + except AttributeError: + raise NotImplementedError("Ext serializable class {:s} is missing implementation of packb()".format(repr(obj.__class__))) elif isinstance(obj, bool): _pack_boolean(obj, fp, options) elif isinstance(obj, int): @@ -764,39 +793,43 @@ ext_type = struct.unpack("b", _read_except(fp, 1))[0] ext_data = _read_except(fp, length) - # Create extension object - ext = Ext(ext_type, ext_data) - # Unpack with ext handler, if we have one ext_handlers = options.get("ext_handlers") - if ext_handlers and ext.type in ext_handlers: - return ext_handlers[ext.type](ext) + if ext_handlers and ext_type in ext_handlers: + return ext_handlers[ext_type](Ext(ext_type, ext_data)) + + # Unpack with ext classes, if type is registered + if ext_type in _ext_classes: + try: + return _ext_classes[ext_type].unpackb(ext_data) + except AttributeError: + raise NotImplementedError("Ext serializable class {:s} is missing implementation of unpackb()".format(repr(_ext_classes[ext_type]))) # Timestamp extension - if ext.type == -1: - return _unpack_ext_timestamp(ext, options) + if ext_type == -1: + return _unpack_ext_timestamp(ext_data, options) - return ext + return Ext(ext_type, ext_data) -def _unpack_ext_timestamp(ext, options): - obj_len = len(ext.data) +def _unpack_ext_timestamp(ext_data, options): + obj_len = len(ext_data) if obj_len == 4: # 32-bit timestamp - seconds = struct.unpack(">I", ext.data)[0] + seconds = struct.unpack(">I", ext_data)[0] microseconds = 0 elif obj_len == 8: # 64-bit timestamp - value = struct.unpack(">Q", ext.data)[0] + value = struct.unpack(">Q", ext_data)[0] seconds = value & 0x3ffffffff microseconds = (value >> 34) // 1000 elif obj_len == 12: # 96-bit timestamp - seconds = struct.unpack(">q", ext.data[4:12])[0] - microseconds = struct.unpack(">I", ext.data[0:4])[0] // 1000 + seconds = struct.unpack(">q", ext_data[4:12])[0] + microseconds = struct.unpack(">I", ext_data[0:4])[0] // 1000 else: raise UnsupportedTimestampException( - "unsupported timestamp with data length %d" % len(ext.data)) + "unsupported timestamp with data length %d" % len(ext_data)) return _epoch + datetime.timedelta(seconds=seconds, microseconds=microseconds) @@ -812,6 +845,9 @@ else: raise Exception("logic error, not array: 0x%02x" % ord(code)) + if options.get('use_tuple'): + return tuple((_unpack(fp, options) for i in xrange(length))) + return [_unpack(fp, options) for i in xrange(length)] @@ -831,8 +867,7 @@ else: raise Exception("logic error, not map: 0x%02x" % ord(code)) - d = {} if not options.get('use_ordered_dict') \ - else collections.OrderedDict() + d = {} if not options.get('use_ordered_dict') else collections.OrderedDict() for _ in xrange(length): # Unpack key k = _unpack(fp, options) @@ -878,6 +913,8 @@ Ext into an object use_ordered_dict (bool): unpack maps into OrderedDict, instead of unordered dict (default False) + use_tuple (bool): unpacks arrays into tuples, instead of lists (default + False) allow_invalid_utf8 (bool): unpack invalid strings into instances of InvalidString, for access to the bytes (default False) @@ -922,6 +959,8 @@ Ext into an object use_ordered_dict (bool): unpack maps into OrderedDict, instead of unordered dict (default False) + use_tuple (bool): unpacks arrays into tuples, instead of lists (default + False) allow_invalid_utf8 (bool): unpack invalid strings into instances of InvalidString, for access to the bytes (default False) @@ -967,6 +1006,8 @@ Ext into an object use_ordered_dict (bool): unpack maps into OrderedDict, instead of unordered dict (default False) + use_tuple (bool): unpacks arrays into tuples, instead of lists (default + False) allow_invalid_utf8 (bool): unpack invalid strings into instances of InvalidString, for access to the bytes (default False) @@ -1015,6 +1056,8 @@ Ext into an object use_ordered_dict (bool): unpack maps into OrderedDict, instead of unordered dict (default False) + use_tuple (bool): unpacks arrays into tuples, instead of lists (default + False) allow_invalid_utf8 (bool): unpack invalid strings into instances of InvalidString, for access to the bytes (default False)