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)


Reply via email to