Hello community,

here is the log from the commit of package python-oslo.serialization for 
openSUSE:Factory checked in at 2016-09-30 15:29:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-oslo.serialization (Old)
 and      /work/SRC/openSUSE:Factory/.python-oslo.serialization.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-oslo.serialization"

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-oslo.serialization/python-oslo.serialization.changes
      2016-05-19 12:14:35.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-oslo.serialization.new/python-oslo.serialization.changes
 2016-09-30 15:29:43.000000000 +0200
@@ -1,0 +2,36 @@
+Fri Sep  2 19:10:06 UTC 2016 - tbecht...@suse.com
+
+- update to version 2.13.0
+  * Fix serialization of binary strings in Python3
+  * Drop H803 in flake8 ignore list
+
+-------------------------------------------------------------------
+Wed Aug 10 12:17:07 UTC 2016 - tbecht...@suse.com
+
+- update to 2.12.0:
+  * Updated from global requirements
+  * Fix parameters of assertEqual are misplaced
+  * Add Python 3.5 classifier and venv
+  * Use {} instead of dict()
+  * Replace TypeError by ValueError in msgpackutils
+  * Support serializing ipaddress objs with jsonutils
+
+-------------------------------------------------------------------
+Sun Jun 19 20:21:39 UTC 2016 - dmuel...@suse.com
+
+- update to 2.7.0:
+  * Trivial: ignore openstack/common in flake8 exclude list
+  * [Trivial] Remove executable privilege of doc/source/conf.py 
+  * Drop babel as requirement since its not used
+  * Updated from global requirements
+  * Unified and simplified API for all serializers
+  * Make msgpack registries copyable (and add __contains__)
+  * msgpack: fix datetime serialization
+
+-------------------------------------------------------------------
+Thu Jun  2 09:21:42 UTC 2016 - tbecht...@suse.com
+
+- use renderspec source service
+- update spec from upstream
+
+-------------------------------------------------------------------

Old:
----
  oslo.serialization-2.4.0.tar.gz

New:
----
  oslo.serialization-2.13.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-oslo.serialization.spec ++++++
--- /var/tmp/diff_new_pack.GDIlhi/_old  2016-09-30 15:29:44.000000000 +0200
+++ /var/tmp/diff_new_pack.GDIlhi/_new  2016-09-30 15:29:44.000000000 +0200
@@ -17,27 +17,26 @@
 
 
 %global sname oslo.serialization
-
 Name:           python-oslo.serialization
-Version:        2.4.0
+Version:        2.13.0
 Release:        0
 Summary:        OpenStack serialization library
 License:        Apache-2.0
 Group:          Development/Languages
 Url:            https://launchpad.net/%{sname}
-Source0:        
https://pypi.python.org/packages/source/o/%{sname}/%{sname}-%{version}.tar.gz
+Source0:        
https://pypi.io/packages/source/o/%{sname}/%{sname}-%{version}.tar.gz
 BuildRequires:  openstack-macros
 BuildRequires:  python-devel
-BuildRequires:  python-mock
+BuildRequires:  python-ipaddress >= 1.0.7
+BuildRequires:  python-mock >= 2.0
+BuildRequires:  python-msgpack-python >= 0.4.0
 BuildRequires:  python-netaddr >= 0.7.12
-BuildRequires:  python-oslo.i18n
-BuildRequires:  python-oslo.utils >= 3.5.0
-BuildRequires:  python-oslotest
-BuildRequires:  python-pbr
-BuildRequires:  python-setuptools
-Requires:       python-Babel >= 1.3
+BuildRequires:  python-oslo.i18n >= 2.1.0
+BuildRequires:  python-oslo.utils >= 3.16.0
+BuildRequires:  python-oslotest >= 1.10.0
+BuildRequires:  python-pbr >= 1.6
 Requires:       python-msgpack-python >= 0.4.0
-Requires:       python-oslo.utils >= 3.5.0
+Requires:       python-oslo.utils >= 3.16.0
 Requires:       python-pytz >= 2013.6
 Requires:       python-six >= 1.9.0
 BuildArch:      noarch
@@ -50,7 +49,7 @@
 Summary:        Documentation for OpenStack serialization library
 Group:          Development/Languages
 BuildRequires:  python-Sphinx
-BuildRequires:  python-oslosphinx >= 2.3.0
+BuildRequires:  python-oslosphinx >= 2.5.0
 
 %description doc
 The oslo.serialization library provides support for representing objects
@@ -61,7 +60,7 @@
 %setup -q -n %{sname}-%{version}
 
 %build
-%{__python2} setup.py build
+%{py2_build}
 
 # generate html docs
 %{__python2} setup.py build_sphinx
@@ -69,10 +68,10 @@
 rm -rf doc/build/html/.{doctrees,buildinfo}
 
 %install
-%{__python2} setup.py install --prefix=%{_prefix} --root=%{buildroot}
+%{py2_install}
 
 %check
-testr init && testr run
+%{__python2} setup.py test
 
 %files
 %license LICENSE

++++++ _service ++++++
--- /var/tmp/diff_new_pack.GDIlhi/_old  2016-09-30 15:29:44.000000000 +0200
+++ /var/tmp/diff_new_pack.GDIlhi/_new  2016-09-30 15:29:44.000000000 +0200
@@ -1,13 +1,13 @@
 <services>
+  <service mode="disabled" name="renderspec">
+    <param 
name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/master/openstack/oslo.serialization/oslo.serialization.spec.j2</param>
+    <param name="output-name">python-oslo.serialization.spec</param>
+    <param 
name="requirements">https://raw.githubusercontent.com/openstack/rpm-packaging/master/global-requirements.txt</param>
+  </service>
   <service mode="disabled" name="download_files">
     <param name="changesgenerate">enable</param>
   </service>
-  <service mode="disabled" name="set_version">
-    <param name="basename">oslo.serialization</param>
-  </service>
   <service name="refresh_patches" mode="disabled">
     <param name="changesgenerate">enable</param>
   </service>
-  <service name="python_requires" mode="disabled">
-  </service>
 </services>

++++++ oslo.serialization-2.4.0.tar.gz -> oslo.serialization-2.13.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.serialization-2.4.0/AUTHORS 
new/oslo.serialization-2.13.0/AUTHORS
--- old/oslo.serialization-2.4.0/AUTHORS        2016-02-25 07:07:39.000000000 
+0100
+++ new/oslo.serialization-2.13.0/AUTHORS       2016-08-10 14:18:40.000000000 
+0200
@@ -15,7 +15,9 @@
 Davanum Srinivas <d...@linux.vnet.ibm.com>
 Dirk Mueller <d...@dmllr.de>
 Doug Hellmann <d...@doughellmann.com>
+Edan David <ed...@mellanox.com>
 Gary Kotton <gkot...@vmware.com>
+Gevorg Davoian <gdavo...@mirantis.com>
 He Jie Xu <x...@linux.vnet.ibm.com>
 Ian Cordasco <graffatcolmin...@gmail.com>
 Ihar Hrachyshka <ihrac...@redhat.com>
@@ -23,14 +25,17 @@
 James Page <james.p...@ubuntu.com>
 Jay Pipes <jaypi...@gmail.com>
 Jeremy Stanley <fu...@yuggoth.org>
+Jim Baker <jim.ba...@python.org>
 Joe Gordon <joe.gord...@gmail.com>
 Joe Gordon <j...@cloudscaling.com>
 Johannes Erdfelt <johannes.erdf...@rackspace.com>
 Joshua Harlow <harlo...@gmail.com>
 Joshua Harlow <harlo...@yahoo-inc.com>
+Joshua Harlow <jxhar...@godaddy.com>
 Julien Danjou <jul...@danjou.info>
 Luis A. Garcia <l...@linux.vnet.ibm.com>
 Matt Riedemann <mrie...@us.ibm.com>
+Mehdi Abaakouk <sil...@redhat.com>
 Mike Heald <mike.he...@hp.com>
 Monty Taylor <mord...@inaugust.com>
 Nataliia Uvarova <grafinya.uvar...@gmail.com>
@@ -45,5 +50,8 @@
 Victor Sergeyev <vserge...@mirantis.com>
 Victor Stinner <vstin...@redhat.com>
 YAMAMOTO Takashi <yamam...@valinux.co.jp>
+ZhiQiang Fan <aji.zq...@gmail.com>
 Zhongyue Luo <lzye...@gmail.com>
 Zhongyue Luo <zhongyue....@intel.com>
+xianming.mao <xianming....@easystack.cn>
+yanheven <yanhe...@qq.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.serialization-2.4.0/ChangeLog 
new/oslo.serialization-2.13.0/ChangeLog
--- old/oslo.serialization-2.4.0/ChangeLog      2016-02-25 07:07:39.000000000 
+0100
+++ new/oslo.serialization-2.13.0/ChangeLog     2016-08-10 14:18:40.000000000 
+0200
@@ -1,6 +1,63 @@
 CHANGES
 =======
 
+2.13.0
+------
+
+* Drop H803 in flake8 ignore list
+* Fix serialization of binary strings in Python3
+
+2.12.0
+------
+
+* Updated from global requirements
+* Fix parameters of assertEqual are misplaced
+* Add Python 3.5 classifier and venv
+
+2.11.0
+------
+
+* Updated from global requirements
+* Updated from global requirements
+* Use {} instead of dict()
+
+2.10.0
+------
+
+* Updated from global requirements
+
+2.9.0
+-----
+
+
+2.8.0
+-----
+
+* Replace TypeError by ValueError in msgpackutils
+* Support serializing ipaddress objs with jsonutils
+* Updated from global requirements
+* Updated from global requirements
+* Updated from global requirements
+
+2.7.0
+-----
+
+* Trivial: ignore openstack/common in flake8 exclude list
+
+2.6.0
+-----
+
+* [Trivial] Remove executable privilege of doc/source/conf.py
+
+2.5.0
+-----
+
+* Drop babel as requirement since its not used
+* Updated from global requirements
+* Unified and simplified API for all serializers
+* Make msgpack registries copyable (and add __contains__)
+* msgpack: fix datetime serialization
+
 2.4.0
 -----
 
@@ -87,7 +144,7 @@
 1.6.0
 -----
 
-* Revert "jsonutils: replace strtime(
+* Revert "jsonutils: replace strtime() usage with isoformat()"
 * jsonutils: encode dict keys
 * jsonutils: simplify simple value handling
 * jsonutils: replace strtime() usage with isoformat()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.serialization-2.4.0/PKG-INFO 
new/oslo.serialization-2.13.0/PKG-INFO
--- old/oslo.serialization-2.4.0/PKG-INFO       2016-02-25 07:07:39.000000000 
+0100
+++ new/oslo.serialization-2.13.0/PKG-INFO      2016-08-10 14:18:40.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: oslo.serialization
-Version: 2.4.0
+Version: 2.13.0
 Summary: Oslo Serialization library
 Home-page: http://launchpad.net/oslo
 Author: OpenStack
@@ -38,3 +38,4 @@
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo.serialization.egg-info/PKG-INFO 
new/oslo.serialization-2.13.0/oslo.serialization.egg-info/PKG-INFO
--- old/oslo.serialization-2.4.0/oslo.serialization.egg-info/PKG-INFO   
2016-02-25 07:07:39.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo.serialization.egg-info/PKG-INFO  
2016-08-10 14:18:40.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: oslo.serialization
-Version: 2.4.0
+Version: 2.13.0
 Summary: Oslo Serialization library
 Home-page: http://launchpad.net/oslo
 Author: OpenStack
@@ -38,3 +38,4 @@
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo.serialization.egg-info/SOURCES.txt 
new/oslo.serialization-2.13.0/oslo.serialization.egg-info/SOURCES.txt
--- old/oslo.serialization-2.4.0/oslo.serialization.egg-info/SOURCES.txt        
2016-02-25 07:07:39.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo.serialization.egg-info/SOURCES.txt       
2016-08-10 14:18:40.000000000 +0200
@@ -30,6 +30,11 @@
 oslo_serialization/base64.py
 oslo_serialization/jsonutils.py
 oslo_serialization/msgpackutils.py
+oslo_serialization/serializer/__init__.py
+oslo_serialization/serializer/base_serializer.py
+oslo_serialization/serializer/json_serializer.py
+oslo_serialization/serializer/msgpack_serializer.py
 oslo_serialization/tests/__init__.py
 oslo_serialization/tests/test_base64.py
-oslo_serialization/tests/test_jsonutils.py
\ No newline at end of file
+oslo_serialization/tests/test_jsonutils.py
+oslo_serialization/tests/test_msgpackutils.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo.serialization.egg-info/pbr.json 
new/oslo.serialization-2.13.0/oslo.serialization.egg-info/pbr.json
--- old/oslo.serialization-2.4.0/oslo.serialization.egg-info/pbr.json   
2016-02-25 07:07:39.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo.serialization.egg-info/pbr.json  
2016-08-10 14:18:40.000000000 +0200
@@ -1 +1 @@
-{"git_version": "6b5116b", "is_release": true}
\ No newline at end of file
+{"git_version": "1f86a66", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo.serialization.egg-info/requires.txt 
new/oslo.serialization-2.13.0/oslo.serialization.egg-info/requires.txt
--- old/oslo.serialization-2.4.0/oslo.serialization.egg-info/requires.txt       
2016-02-25 07:07:39.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo.serialization.egg-info/requires.txt      
2016-08-10 14:18:40.000000000 +0200
@@ -1,6 +1,5 @@
 pbr>=1.6
-Babel>=1.3
 six>=1.9.0
 msgpack-python>=0.4.0
-oslo.utils>=3.5.0
+oslo.utils>=3.16.0
 pytz>=2013.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo_serialization/jsonutils.py 
new/oslo.serialization-2.13.0/oslo_serialization/jsonutils.py
--- old/oslo.serialization-2.4.0/oslo_serialization/jsonutils.py        
2016-02-25 07:07:09.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo_serialization/jsonutils.py       
2016-08-10 14:17:11.000000000 +0200
@@ -43,6 +43,7 @@
 import six
 import six.moves.xmlrpc_client as xmlrpclib
 
+ipaddress = importutils.try_import("ipaddress")
 netaddr = importutils.try_import("netaddr")
 
 _nasty_type_tests = [inspect.ismodule, inspect.isclass, inspect.ismethod,
@@ -51,12 +52,12 @@
                      inspect.iscode, inspect.isbuiltin, inspect.isroutine,
                      inspect.isabstract]
 
-_simple_types = (six.string_types + six.integer_types
+_simple_types = ((six.text_type,) + six.integer_types
                  + (type(None), bool, float))
 
 
 def to_primitive(value, convert_instances=False, convert_datetime=True,
-                 level=0, max_depth=3):
+                 level=0, max_depth=3, encoding='utf-8'):
     """Convert a complex object into primitives.
 
     Handy for JSON serialization. We can optionally handle instances,
@@ -91,6 +92,11 @@
     if isinstance(value, _simple_types):
         return value
 
+    if isinstance(value, six.binary_type):
+        if six.PY3:
+            value = value.decode(encoding=encoding)
+        return value
+
     # It's not clear why xmlrpclib created their own DateTime type, but
     # for our purposes, make it a datetime type which is explicitly
     # handled
@@ -109,6 +115,11 @@
     if netaddr and isinstance(value, netaddr.IPAddress):
         return six.text_type(value)
 
+    if ipaddress and isinstance(value,
+                                (ipaddress.IPv4Address,
+                                 ipaddress.IPv6Address)):
+        return six.text_type(value)
+
     # value of itertools.count doesn't get caught by nasty_type_tests
     # and results in infinite loop when list(value) is called.
     if type(value) == itertools.count:
@@ -126,7 +137,7 @@
         return 'mock'
 
     if level > max_depth:
-        return '?'
+        return None
 
     # The try block may not be necessary after the class check above,
     # but just in case ...
@@ -135,10 +146,11 @@
                                       convert_instances=convert_instances,
                                       convert_datetime=convert_datetime,
                                       level=level,
-                                      max_depth=max_depth)
+                                      max_depth=max_depth,
+                                      encoding=encoding)
         if isinstance(value, dict):
-            return dict((recursive(k), recursive(v))
-                        for k, v in six.iteritems(value))
+            return {recursive(k): recursive(v)
+                    for k, v in six.iteritems(value)}
         elif hasattr(value, 'iteritems'):
             return recursive(dict(value.iteritems()), level=level + 1)
         # Python 3 does not have iteritems
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo_serialization/msgpackutils.py 
new/oslo.serialization-2.13.0/oslo_serialization/msgpackutils.py
--- old/oslo.serialization-2.4.0/oslo_serialization/msgpackutils.py     
2016-02-25 07:07:09.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo_serialization/msgpackutils.py    
2016-08-10 14:17:11.000000000 +0200
@@ -13,7 +13,7 @@
 #    under the License.
 
 '''
-Msgpack related utilities.
+MessagePack related utilities.
 
 This module provides a few things:
 
@@ -41,6 +41,36 @@
 
 netaddr = importutils.try_import("netaddr")
 
+
+class Interval(object):
+    """Small and/or simple immutable integer/float interval class.
+
+    Interval checking is **inclusive** of the min/max boundaries.
+    """
+
+    def __init__(self, min_value, max_value):
+        if min_value > max_value:
+            raise ValueError("Minimum value %s must be less than"
+                             " or equal to maximum value %s" % (min_value,
+                                                                max_value))
+        self._min_value = min_value
+        self._max_value = max_value
+
+    @property
+    def min_value(self):
+        return self._min_value
+
+    @property
+    def max_value(self):
+        return self._max_value
+
+    def __contains__(self, value):
+        return value >= self.min_value and value <= self.max_value
+
+    def __repr__(self):
+        return 'Interval(%s, %s)' % (self._min_value, self._max_value)
+
+
 # Expose these so that users don't have to import msgpack to gain these.
 
 PackException = msgpack.PackException
@@ -61,48 +91,115 @@
     .. versionadded:: 1.5
     """
 
-    # Applications can assign 0 to 127 to store
-    # application-specific type information...
+    reserved_extension_range = Interval(0, 32)
+    """
+    These ranges are **always** reserved for use by ``oslo.serialization`` and
+    its own add-ons extensions (these extensions are meant to be generally
+    applicable to all of python).
+    """
+
+    non_reserved_extension_range = Interval(33, 127)
+    """
+    These ranges are **always** reserved for use by applications building
+    their own type specific handlers (the meaning of extensions in this range
+    will typically vary depending on application).
+    """
+
     min_value = 0
+    """
+    Applications can assign 0 to 127 to store application (or library)
+    specific type handlers; see above ranges for what is reserved by this
+    library and what is not.
+    """
+
     max_value = 127
+    """
+    Applications can assign 0 to 127 to store application (or library)
+    specific type handlers; see above ranges for what is reserved by this
+    library and what is not.
+    """
 
     def __init__(self):
         self._handlers = {}
+        self._num_handlers = 0
         self.frozen = False
 
     def __iter__(self):
-        return six.itervalues(self._handlers)
+        """Iterates over **all** registered handlers."""
+        for handlers in six.itervalues(self._handlers):
+            for h in handlers:
+                yield h
 
-    def register(self, handler):
+    def register(self, handler, reserved=False, override=False):
         """Register a extension handler to handle its associated type."""
         if self.frozen:
             raise ValueError("Frozen handler registry can't be modified")
+        if reserved:
+            ok_interval = self.reserved_extension_range
+        else:
+            ok_interval = self.non_reserved_extension_range
         ident = handler.identity
-        if ident < self.min_value:
+        if ident < ok_interval.min_value:
             raise ValueError("Handler '%s' identity must be greater"
-                             " or equal to %s" % (handler, self.min_value))
-        if ident > self.max_value:
+                             " or equal to %s" % (handler,
+                                                  ok_interval.min_value))
+        if ident > ok_interval.max_value:
             raise ValueError("Handler '%s' identity must be less than"
-                             " or equal to %s" % (handler, self.max_value))
-        if ident in self._handlers:
-            raise ValueError("Already registered handler with"
+                             " or equal to %s" % (handler,
+                                                  ok_interval.max_value))
+        if ident in self._handlers and override:
+            existing_handlers = self._handlers[ident]
+            # Insert at the front so that overrides get selected before
+            # whatever existed before the override...
+            existing_handlers.insert(0, handler)
+            self._num_handlers += 1
+        elif ident in self._handlers and not override:
+            raise ValueError("Already registered handler(s) with"
                              " identity %s: %s" % (ident,
                                                    self._handlers[ident]))
         else:
-            self._handlers[ident] = handler
+            self._handlers[ident] = [handler]
+            self._num_handlers += 1
 
     def __len__(self):
-        return len(self._handlers)
+        """Return how many extension handlers are registered."""
+        return self._num_handlers
+
+    def __contains__(self, identity):
+        """Return if any handler exists for the given identity (number)."""
+        return identity in self._handlers
+
+    def copy(self, unfreeze=False):
+        """Deep copy the given registry (and its handlers)."""
+        c = type(self)()
+        for ident, handlers in six.iteritems(self._handlers):
+            cloned_handlers = []
+            for h in handlers:
+                if hasattr(h, 'copy'):
+                    h = h.copy(c)
+                cloned_handlers.append(h)
+            c._handlers[ident] = cloned_handlers
+            c._num_handlers += len(cloned_handlers)
+        if not unfreeze and self.frozen:
+            c.frozen = True
+        return c
 
     def get(self, identity):
-        """Get the handle for the given numeric identity (or none)."""
-        return self._handlers.get(identity, None)
+        """Get the handler for the given numeric identity (or none)."""
+        maybe_handlers = self._handlers.get(identity)
+        if maybe_handlers:
+            # Prefer the first (if there are many) as this is how we
+            # override built-in extensions (for those that wish to do this).
+            return maybe_handlers[0]
+        else:
+            return None
 
     def match(self, obj):
         """Match the registries handlers to the given object (or none)."""
-        for handler in six.itervalues(self._handlers):
-            if isinstance(obj, handler.handles):
-                return handler
+        for possible_handlers in six.itervalues(self._handlers):
+            for h in possible_handlers:
+                if isinstance(obj, h.handles):
+                    return h
         return None
 
 
@@ -126,22 +223,42 @@
     def __init__(self, registry):
         self._registry = registry
 
+    def copy(self, registry):
+        return type(self)(registry)
+
     def serialize(self, dt):
         dct = {
-            'day': dt.day,
-            'month': dt.month,
-            'year': dt.year,
-            'hour': dt.hour,
-            'minute': dt.minute,
-            'second': dt.second,
-            'microsecond': dt.microsecond,
+            u'day': dt.day,
+            u'month': dt.month,
+            u'year': dt.year,
+            u'hour': dt.hour,
+            u'minute': dt.minute,
+            u'second': dt.second,
+            u'microsecond': dt.microsecond,
         }
         if dt.tzinfo:
-            dct['tz'] = dt.tzinfo.tzname(None)
+            tz = dt.tzinfo.tzname(None)
+            if six.PY2:
+                tz = tz.decode("ascii")
+            dct[u'tz'] = tz
         return dumps(dct, registry=self._registry)
 
     def deserialize(self, blob):
         dct = loads(blob, registry=self._registry)
+
+        if six.PY3 and b"day" in dct:
+            # NOTE(sileht): oslo.serialization <= 2.4.1 was
+            # storing thing as unicode for py3 while is was
+            # bytes for py2
+            # For python2, we don't care bytes or unicode works
+            # for dict keys and tz
+            # But for python3, we have some backward compability
+            # to take care in case of the payload have been produced
+            # by python2 and now read by python3
+            dct = dict((k.decode("ascii"), v) for k, v in dct.items())
+            if 'tz' in dct:
+                dct['tz'] = dct['tz'].decode("ascii")
+
         dt = datetime.datetime(day=dct['day'],
                                month=dct['month'],
                                year=dct['year'],
@@ -205,6 +322,9 @@
     def __init__(self, registry):
         self._registry = registry
 
+    def copy(self, registry):
+        return type(self)(registry)
+
     def serialize(self, obj):
         return dumps(list(obj), registry=self._registry)
 
@@ -224,6 +344,9 @@
     def __init__(self, registry):
         self._handler = DateTimeHandler(registry)
 
+    def copy(self, registry):
+        return type(self)(registry)
+
     def serialize(self, obj):
         dt = datetime.datetime(*tuple(obj.timetuple())[:6])
         return self._handler.serialize(dt)
@@ -240,16 +363,23 @@
     def __init__(self, registry):
         self._registry = registry
 
+    def copy(self, registry):
+        return type(self)(registry)
+
     def serialize(self, d):
         dct = {
-            'year': d.year,
-            'month': d.month,
-            'day': d.day,
+            u'year': d.year,
+            u'month': d.month,
+            u'day': d.day,
         }
         return dumps(dct, registry=self._registry)
 
     def deserialize(self, blob):
         dct = loads(blob, registry=self._registry)
+        if six.PY3 and b"day" in dct:
+            # NOTE(sileht): see DateTimeHandler.deserialize()
+            dct = dict((k.decode("ascii"), v) for k, v in dct.items())
+
         return datetime.date(year=dct['year'],
                              month=dct['month'],
                              day=dct['day'])
@@ -258,14 +388,14 @@
 def _serializer(registry, obj):
     handler = registry.match(obj)
     if handler is None:
-        raise TypeError("No serialization handler registered"
-                        " for type '%s'" % (type(obj).__name__))
+        raise ValueError("No serialization handler registered"
+                         " for type '%s'" % (type(obj).__name__))
     return msgpack.ExtType(handler.identity, handler.serialize(obj))
 
 
 def _unserializer(registry, code, data):
     handler = registry.get(code)
-    if handler is None:
+    if not handler:
         return msgpack.ExtType(code, data)
     else:
         return handler.deserialize(data)
@@ -273,15 +403,15 @@
 
 def _create_default_registry():
     registry = HandlerRegistry()
-    registry.register(DateTimeHandler(registry))
-    registry.register(DateHandler(registry))
-    registry.register(UUIDHandler())
-    registry.register(CountHandler())
-    registry.register(SetHandler(registry))
-    registry.register(FrozenSetHandler(registry))
+    registry.register(DateTimeHandler(registry), reserved=True)
+    registry.register(DateHandler(registry), reserved=True)
+    registry.register(UUIDHandler(), reserved=True)
+    registry.register(CountHandler(), reserved=True)
+    registry.register(SetHandler(registry), reserved=True)
+    registry.register(FrozenSetHandler(registry), reserved=True)
     if netaddr is not None:
-        registry.register(NetAddrIPHandler())
-    registry.register(XMLRPCDateTimeHandler(registry))
+        registry.register(NetAddrIPHandler(), reserved=True)
+    registry.register(XMLRPCDateTimeHandler(registry), reserved=True)
     registry.frozen = True
     return registry
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo_serialization/serializer/base_serializer.py 
new/oslo.serialization-2.13.0/oslo_serialization/serializer/base_serializer.py
--- 
old/oslo.serialization-2.4.0/oslo_serialization/serializer/base_serializer.py   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/oslo.serialization-2.13.0/oslo_serialization/serializer/base_serializer.py  
    2016-08-10 14:17:11.000000000 +0200
@@ -0,0 +1,58 @@
+#    Copyright 2016 Mirantis, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+"""
+Unified and simplified API for oslo.serialization's serializers.
+"""
+
+
+import abc
+import six
+
+
+@six.add_metaclass(abc.ABCMeta)
+class BaseSerializer(object):
+    """Generic (de-)serialization definition abstract base class."""
+
+    @abc.abstractmethod
+    def dump(self, obj, fp):
+        """Serialize ``obj`` as a stream to ``fp``.
+
+        :param obj: python object to be serialized
+        :param fp: ``.write()``-supporting file-like object
+        """
+
+    @abc.abstractmethod
+    def dump_as_bytes(self, obj):
+        """Serialize ``obj`` to a byte string.
+
+        :param obj: python object to be serialized
+        :returns: byte string
+        """
+
+    @abc.abstractmethod
+    def load(self, fp):
+        """Deserialize ``fp`` to a python object.
+
+        :param fp: ``.read()``-supporting file-like object
+        :returns: python object
+        """
+
+    @abc.abstractmethod
+    def load_from_bytes(self, s):
+        """Deserialize ``s`` to a python object.
+
+        :param s: byte string to be deserialized
+        :returns: python object
+        """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo_serialization/serializer/json_serializer.py 
new/oslo.serialization-2.13.0/oslo_serialization/serializer/json_serializer.py
--- 
old/oslo.serialization-2.4.0/oslo_serialization/serializer/json_serializer.py   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/oslo.serialization-2.13.0/oslo_serialization/serializer/json_serializer.py  
    2016-08-10 14:17:11.000000000 +0200
@@ -0,0 +1,38 @@
+#    Copyright 2016 Mirantis, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+from oslo_serialization import jsonutils
+from oslo_serialization.serializer.base_serializer import BaseSerializer
+
+
+class JSONSerializer(BaseSerializer):
+    """JSON serializer based on the jsonutils module."""
+
+    def __init__(self, default=jsonutils.to_primitive, encoding='utf-8'):
+        self._default = default
+        self._encoding = encoding
+
+    def dump(self, obj, fp):
+        return jsonutils.dump(obj, fp)
+
+    def dump_as_bytes(self, obj):
+        return jsonutils.dump_as_bytes(obj, default=self._default,
+                                       encoding=self._encoding)
+
+    def load(self, fp):
+        return jsonutils.load(fp, encoding=self._encoding)
+
+    def load_from_bytes(self, s):
+        return jsonutils.loads(s, encoding=self._encoding)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo_serialization/serializer/msgpack_serializer.py
 
new/oslo.serialization-2.13.0/oslo_serialization/serializer/msgpack_serializer.py
--- 
old/oslo.serialization-2.4.0/oslo_serialization/serializer/msgpack_serializer.py
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/oslo.serialization-2.13.0/oslo_serialization/serializer/msgpack_serializer.py
   2016-08-10 14:17:11.000000000 +0200
@@ -0,0 +1,36 @@
+#    Copyright 2016 Mirantis, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+from oslo_serialization import msgpackutils
+from oslo_serialization.serializer.base_serializer import BaseSerializer
+
+
+class MessagePackSerializer(BaseSerializer):
+    """MessagePack serializer based on the msgpackutils module."""
+
+    def __init__(self, registry=None):
+        self._registry = registry
+
+    def dump(self, obj, fp):
+        return msgpackutils.dump(obj, fp, registry=self._registry)
+
+    def dump_as_bytes(self, obj):
+        return msgpackutils.dumps(obj, registry=self._registry)
+
+    def load(self, fp):
+        return msgpackutils.load(fp, registry=self._registry)
+
+    def load_from_bytes(self, s):
+        return msgpackutils.loads(s, registry=self._registry)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo_serialization/tests/test_base64.py 
new/oslo.serialization-2.13.0/oslo_serialization/tests/test_base64.py
--- old/oslo.serialization-2.4.0/oslo_serialization/tests/test_base64.py        
2016-02-25 07:07:09.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo_serialization/tests/test_base64.py       
2016-08-10 14:17:11.000000000 +0200
@@ -20,37 +20,37 @@
 class Base64Tests(test_base.BaseTestCase):
 
     def test_encode_as_bytes(self):
-        self.assertEqual(base64.encode_as_bytes(b'text'),
-                         b'dGV4dA==')
-        self.assertEqual(base64.encode_as_bytes(u'text'),
-                         b'dGV4dA==')
-        self.assertEqual(base64.encode_as_bytes(u'e:\xe9'),
-                         b'ZTrDqQ==')
-        self.assertEqual(base64.encode_as_bytes(u'e:\xe9', encoding='latin1'),
-                         b'ZTrp')
+        self.assertEqual(b'dGV4dA==',
+                         base64.encode_as_bytes(b'text'))
+        self.assertEqual(b'dGV4dA==',
+                         base64.encode_as_bytes(u'text'))
+        self.assertEqual(b'ZTrDqQ==',
+                         base64.encode_as_bytes(u'e:\xe9'))
+        self.assertEqual(b'ZTrp',
+                         base64.encode_as_bytes(u'e:\xe9', encoding='latin1'))
 
     def test_encode_as_text(self):
-        self.assertEqual(base64.encode_as_text(b'text'),
-                         u'dGV4dA==')
-        self.assertEqual(base64.encode_as_text(u'text'),
-                         u'dGV4dA==')
-        self.assertEqual(base64.encode_as_text(u'e:\xe9'),
-                         u'ZTrDqQ==')
-        self.assertEqual(base64.encode_as_text(u'e:\xe9', encoding='latin1'),
-                         u'ZTrp')
+        self.assertEqual(u'dGV4dA==',
+                         base64.encode_as_text(b'text'))
+        self.assertEqual(u'dGV4dA==',
+                         base64.encode_as_text(u'text'))
+        self.assertEqual(u'ZTrDqQ==',
+                         base64.encode_as_text(u'e:\xe9'))
+        self.assertEqual(u'ZTrp',
+                         base64.encode_as_text(u'e:\xe9', encoding='latin1'))
 
     def test_decode_as_bytes(self):
-        self.assertEqual(base64.decode_as_bytes(b'dGV4dA=='),
-                         b'text')
-        self.assertEqual(base64.decode_as_bytes(u'dGV4dA=='),
-                         b'text')
+        self.assertEqual(b'text',
+                         base64.decode_as_bytes(b'dGV4dA=='))
+        self.assertEqual(b'text',
+                         base64.decode_as_bytes(u'dGV4dA=='))
 
     def test_decode_as_text(self):
-        self.assertEqual(base64.decode_as_text(b'dGV4dA=='),
-                         u'text')
-        self.assertEqual(base64.decode_as_text(u'dGV4dA=='),
-                         u'text')
-        self.assertEqual(base64.decode_as_text(u'ZTrDqQ=='),
-                         u'e:\xe9')
-        self.assertEqual(base64.decode_as_text(u'ZTrp', encoding='latin1'),
-                         u'e:\xe9')
+        self.assertEqual(u'text',
+                         base64.decode_as_text(b'dGV4dA=='))
+        self.assertEqual(u'text',
+                         base64.decode_as_text(u'dGV4dA=='))
+        self.assertEqual(u'e:\xe9',
+                         base64.decode_as_text(u'ZTrDqQ=='))
+        self.assertEqual(u'e:\xe9',
+                         base64.decode_as_text(u'ZTrp', encoding='latin1'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo_serialization/tests/test_jsonutils.py 
new/oslo.serialization-2.13.0/oslo_serialization/tests/test_jsonutils.py
--- old/oslo.serialization-2.4.0/oslo_serialization/tests/test_jsonutils.py     
2016-02-25 07:07:09.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo_serialization/tests/test_jsonutils.py    
2016-08-10 14:17:11.000000000 +0200
@@ -15,6 +15,7 @@
 
 import collections
 import datetime
+import ipaddress
 import json
 
 import mock
@@ -112,36 +113,39 @@
         super(ToPrimitiveTestCase, self).setUp()
         self.trans_fixture = self.useFixture(fixture.Translation())
 
+    def test_bytes(self):
+        self.assertEqual(jsonutils.to_primitive(b'abc'), 'abc')
+
     def test_list(self):
-        self.assertEqual(jsonutils.to_primitive([1, 2, 3]), [1, 2, 3])
+        self.assertEqual([1, 2, 3], jsonutils.to_primitive([1, 2, 3]))
 
     def test_empty_list(self):
-        self.assertEqual(jsonutils.to_primitive([]), [])
+        self.assertEqual([], jsonutils.to_primitive([]))
 
     def test_tuple(self):
-        self.assertEqual(jsonutils.to_primitive((1, 2, 3)), [1, 2, 3])
+        self.assertEqual([1, 2, 3], jsonutils.to_primitive((1, 2, 3)))
 
     def test_dict(self):
-        self.assertEqual(jsonutils.to_primitive(dict(a=1, b=2, c=3)),
-                         dict(a=1, b=2, c=3))
+        self.assertEqual(dict(a=1, b=2, c=3),
+                         jsonutils.to_primitive(dict(a=1, b=2, c=3)))
 
     def test_empty_dict(self):
-        self.assertEqual(jsonutils.to_primitive({}), {})
+        self.assertEqual({}, jsonutils.to_primitive({}))
 
     def test_datetime(self):
         x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
-        self.assertEqual(jsonutils.to_primitive(x),
-                         '1920-02-03T04:05:06.000007')
+        self.assertEqual('1920-02-03T04:05:06.000007',
+                         jsonutils.to_primitive(x))
 
     def test_datetime_preserve(self):
         x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
-        self.assertEqual(jsonutils.to_primitive(x, convert_datetime=False), x)
+        self.assertEqual(x, jsonutils.to_primitive(x, convert_datetime=False))
 
     def test_DateTime(self):
         x = xmlrpclib.DateTime()
         x.decode("19710203T04:05:06")
-        self.assertEqual(jsonutils.to_primitive(x),
-                         '1971-02-03T04:05:06.000000')
+        self.assertEqual('1971-02-03T04:05:06.000000',
+                         jsonutils.to_primitive(x))
 
     def test_iter(self):
         class IterClass(object):
@@ -160,7 +164,7 @@
             __next__ = next
 
         x = IterClass()
-        self.assertEqual(jsonutils.to_primitive(x), [1, 2, 3, 4, 5])
+        self.assertEqual([1, 2, 3, 4, 5], jsonutils.to_primitive(x))
 
     def test_iteritems(self):
         class IterItemsClass(object):
@@ -173,7 +177,7 @@
 
         x = IterItemsClass()
         p = jsonutils.to_primitive(x)
-        self.assertEqual(p, {'a': 1, 'b': 2, 'c': 3})
+        self.assertEqual({'a': 1, 'b': 2, 'c': 3}, p)
 
     def test_iteritems_with_cycle(self):
         class IterItemsClass(object):
@@ -204,7 +208,7 @@
 
         x = ItemsClass()
         p = jsonutils.to_primitive(x)
-        self.assertEqual(p, {'a': 1, 'b': 2, 'c': 3})
+        self.assertEqual({'a': 1, 'b': 2, 'c': 3}, p)
 
     def test_precedence_items_iteritems(self):
         class ItemsIterItemsClass(object):
@@ -217,7 +221,7 @@
         x = ItemsIterItemsClass()
         p = jsonutils.to_primitive(x)
         # Prefer iteritems over items
-        self.assertEqual(p, {'iteritems': 'iteritems'})
+        self.assertEqual({'iteritems': 'iteritems'}, p)
 
     def test_mapping(self):
         # Make sure collections.Mapping is converted to a dict
@@ -237,7 +241,7 @@
 
         x = MappingClass()
         p = jsonutils.to_primitive(x)
-        self.assertEqual(p, {'a': 1, 'b': 2, 'c': 3})
+        self.assertEqual({'a': 1, 'b': 2, 'c': 3}, p)
 
     def test_instance(self):
         class MysteryClass(object):
@@ -247,24 +251,24 @@
                 self.b = 1
 
         x = MysteryClass()
-        self.assertEqual(jsonutils.to_primitive(x, convert_instances=True),
-                         dict(b=1))
+        self.assertEqual(dict(b=1),
+                         jsonutils.to_primitive(x, convert_instances=True))
 
-        self.assertEqual(jsonutils.to_primitive(x), x)
+        self.assertEqual(x, jsonutils.to_primitive(x))
 
     def test_typeerror(self):
         x = bytearray  # Class, not instance
         if six.PY3:
-            self.assertEqual(jsonutils.to_primitive(x), u"<class 'bytearray'>")
+            self.assertEqual(u"<class 'bytearray'>", jsonutils.to_primitive(x))
         else:
-            self.assertEqual(jsonutils.to_primitive(x), u"<type 'bytearray'>")
+            self.assertEqual(u"<type 'bytearray'>", jsonutils.to_primitive(x))
 
     def test_nasties(self):
         def foo():
             pass
         x = [datetime, foo, dir]
         ret = jsonutils.to_primitive(x)
-        self.assertEqual(len(ret), 3)
+        self.assertEqual(3, len(ret))
         self.assertTrue(ret[0].startswith(u"<module 'datetime' from ") or
                         ret[0].startswith(u"<module 'datetime' (built-in)"))
         if six.PY3:
@@ -273,7 +277,7 @@
             ))
         else:
             self.assertTrue(ret[1].startswith('<function foo at 0x'))
-        self.assertEqual(ret[2], '<built-in function dir>')
+        self.assertEqual('<built-in function dir>', ret[2])
 
     def test_depth(self):
         class LevelsGenerator(object):
@@ -288,24 +292,34 @@
 
         l4_obj = LevelsGenerator(4)
 
-        json_l2 = {0: {0: '?'}}
-        json_l3 = {0: {0: {0: '?'}}}
-        json_l4 = {0: {0: {0: {0: '?'}}}}
+        json_l2 = {0: {0: None}}
+        json_l3 = {0: {0: {0: None}}}
+        json_l4 = {0: {0: {0: {0: None}}}}
 
         ret = jsonutils.to_primitive(l4_obj, max_depth=2)
-        self.assertEqual(ret, json_l2)
+        self.assertEqual(json_l2, ret)
 
         ret = jsonutils.to_primitive(l4_obj, max_depth=3)
-        self.assertEqual(ret, json_l3)
+        self.assertEqual(json_l3, ret)
 
         ret = jsonutils.to_primitive(l4_obj, max_depth=4)
-        self.assertEqual(ret, json_l4)
+        self.assertEqual(json_l4, ret)
 
-    def test_ipaddr(self):
+    def test_ipaddr_using_netaddr(self):
         thing = {'ip_addr': netaddr.IPAddress('1.2.3.4')}
         ret = jsonutils.to_primitive(thing)
         self.assertEqual({'ip_addr': '1.2.3.4'}, ret)
 
+    def test_ipaddr_using_ipaddress_v4(self):
+        thing = {'ip_addr': ipaddress.ip_address(u'192.168.0.1')}
+        ret = jsonutils.to_primitive(thing)
+        self.assertEqual({'ip_addr': '192.168.0.1'}, ret)
+
+    def test_ipaddr_using_ipaddress_v6(self):
+        thing = {'ip_addr': ipaddress.ip_address(u'2001:db8::')}
+        ret = jsonutils.to_primitive(thing)
+        self.assertEqual({'ip_addr': '2001:db8::'}, ret)
+
     def test_message_with_param(self):
         msg = self.trans_fixture.lazy('A message with param: %s')
         msg = msg % 'test_domain'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.serialization-2.4.0/oslo_serialization/tests/test_msgpackutils.py 
new/oslo.serialization-2.13.0/oslo_serialization/tests/test_msgpackutils.py
--- old/oslo.serialization-2.4.0/oslo_serialization/tests/test_msgpackutils.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/oslo.serialization-2.13.0/oslo_serialization/tests/test_msgpackutils.py 
2016-08-10 14:17:11.000000000 +0200
@@ -0,0 +1,214 @@
+#    Copyright (C) 2015 Yahoo! Inc. All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import datetime
+import itertools
+import uuid
+
+import netaddr
+from oslotest import base as test_base
+from pytz import timezone
+import six
+import six.moves.xmlrpc_client as xmlrpclib
+
+from oslo_serialization import msgpackutils
+
+
+_TZ_FMT = '%Y-%m-%d %H:%M:%S %Z%z'
+
+
+class Color(object):
+    def __init__(self, r, g, b):
+        self.r = r
+        self.g = g
+        self.b = b
+
+
+class ColorHandler(object):
+    handles = (Color,)
+    identity = (
+        msgpackutils.HandlerRegistry.non_reserved_extension_range.min_value + 1
+    )
+
+    @staticmethod
+    def serialize(obj):
+        blob = '%s, %s, %s' % (obj.r, obj.g, obj.b)
+        if six.PY3:
+            blob = blob.encode("ascii")
+        return blob
+
+    @staticmethod
+    def deserialize(data):
+        chunks = [int(c.strip()) for c in data.split(b",")]
+        return Color(chunks[0], chunks[1], chunks[2])
+
+
+class MySpecialSetHandler(object):
+    handles = (set,)
+    identity = msgpackutils.SetHandler.identity
+
+
+def _dumps_loads(obj):
+    obj = msgpackutils.dumps(obj)
+    return msgpackutils.loads(obj)
+
+
+class MsgPackUtilsTest(test_base.BaseTestCase):
+    def test_list(self):
+        self.assertEqual([1, 2, 3], _dumps_loads([1, 2, 3]))
+
+    def test_empty_list(self):
+        self.assertEqual([], _dumps_loads([]))
+
+    def test_tuple(self):
+        # Seems like we do lose whether it was a tuple or not...
+        #
+        # Maybe fixed someday:
+        #
+        # https://github.com/msgpack/msgpack-python/issues/98
+        self.assertEqual([1, 2, 3], _dumps_loads((1, 2, 3)))
+
+    def test_dict(self):
+        self.assertEqual(dict(a=1, b=2, c=3),
+                         _dumps_loads(dict(a=1, b=2, c=3)))
+
+    def test_empty_dict(self):
+        self.assertEqual({}, _dumps_loads({}))
+
+    def test_complex_dict(self):
+        src = {
+            'now': datetime.datetime(1920, 2, 3, 4, 5, 6, 7),
+            'later': datetime.datetime(1921, 2, 3, 4, 5, 6, 9),
+            'a': 1,
+            'b': 2.0,
+            'c': [],
+            'd': set([1, 2, 3]),
+            'zzz': uuid.uuid4(),
+            'yyy': 'yyy',
+            'ddd': b'bbb',
+            'today': datetime.date.today(),
+        }
+        self.assertEqual(src, _dumps_loads(src))
+
+    def test_itercount(self):
+        it = itertools.count(1)
+        six.next(it)
+        six.next(it)
+        it2 = _dumps_loads(it)
+        self.assertEqual(six.next(it), six.next(it2))
+
+        it = itertools.count(0)
+        it2 = _dumps_loads(it)
+        self.assertEqual(six.next(it), six.next(it2))
+
+    def test_itercount_step(self):
+        it = itertools.count(1, 3)
+        it2 = _dumps_loads(it)
+        self.assertEqual(six.next(it), six.next(it2))
+
+    def test_set(self):
+        self.assertEqual(set([1, 2]), _dumps_loads(set([1, 2])))
+
+    def test_empty_set(self):
+        self.assertEqual(set([]), _dumps_loads(set([])))
+
+    def test_frozenset(self):
+        self.assertEqual(frozenset([1, 2]), _dumps_loads(frozenset([1, 2])))
+
+    def test_empty_frozenset(self):
+        self.assertEqual(frozenset([]), _dumps_loads(frozenset([])))
+
+    def test_datetime_preserve(self):
+        x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
+        self.assertEqual(x, _dumps_loads(x))
+
+    def test_datetime(self):
+        x = xmlrpclib.DateTime()
+        x.decode("19710203T04:05:06")
+        self.assertEqual(x, _dumps_loads(x))
+
+    def test_ipaddr(self):
+        thing = {'ip_addr': netaddr.IPAddress('1.2.3.4')}
+        self.assertEqual(thing, _dumps_loads(thing))
+
+    def test_today(self):
+        today = datetime.date.today()
+        self.assertEqual(today, _dumps_loads(today))
+
+    def test_datetime_tz_clone(self):
+        eastern = timezone('US/Eastern')
+        now = datetime.datetime.now()
+        e_dt = eastern.localize(now)
+        e_dt2 = _dumps_loads(e_dt)
+        self.assertEqual(e_dt, e_dt2)
+        self.assertEqual(e_dt.strftime(_TZ_FMT), e_dt2.strftime(_TZ_FMT))
+
+    def test_datetime_tz_different(self):
+        eastern = timezone('US/Eastern')
+        pacific = timezone('US/Pacific')
+        now = datetime.datetime.now()
+
+        e_dt = eastern.localize(now)
+        p_dt = pacific.localize(now)
+
+        self.assertNotEqual(e_dt, p_dt)
+        self.assertNotEqual(e_dt.strftime(_TZ_FMT), p_dt.strftime(_TZ_FMT))
+
+        e_dt2 = _dumps_loads(e_dt)
+        p_dt2 = _dumps_loads(p_dt)
+
+        self.assertNotEqual(e_dt2, p_dt2)
+        self.assertNotEqual(e_dt2.strftime(_TZ_FMT), p_dt2.strftime(_TZ_FMT))
+
+        self.assertEqual(e_dt, e_dt2)
+        self.assertEqual(p_dt, p_dt2)
+
+    def test_copy_then_register(self):
+        registry = msgpackutils.default_registry
+        self.assertRaises(ValueError,
+                          registry.register, MySpecialSetHandler(),
+                          reserved=True, override=True)
+        registry = registry.copy(unfreeze=True)
+        registry.register(MySpecialSetHandler(),
+                          reserved=True, override=True)
+        h = registry.match(set())
+        self.assertIsInstance(h, MySpecialSetHandler)
+
+    def test_bad_register(self):
+        registry = msgpackutils.default_registry
+        self.assertRaises(ValueError,
+                          registry.register, MySpecialSetHandler(),
+                          reserved=True, override=True)
+        self.assertRaises(ValueError,
+                          registry.register, MySpecialSetHandler())
+        registry = registry.copy(unfreeze=True)
+        registry.register(ColorHandler())
+
+        self.assertRaises(ValueError,
+                          registry.register, ColorHandler())
+
+    def test_custom_register(self):
+        registry = msgpackutils.default_registry.copy(unfreeze=True)
+        registry.register(ColorHandler())
+
+        c = Color(255, 254, 253)
+        c_b = msgpackutils.dumps(c, registry=registry)
+        c = msgpackutils.loads(c_b, registry=registry)
+
+        self.assertEqual(255, c.r)
+        self.assertEqual(254, c.g)
+        self.assertEqual(253, c.b)
+
+    def test_object(self):
+        self.assertRaises(ValueError, msgpackutils.dumps, object())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.serialization-2.4.0/requirements.txt 
new/oslo.serialization-2.13.0/requirements.txt
--- old/oslo.serialization-2.4.0/requirements.txt       2016-02-25 
07:07:09.000000000 +0100
+++ new/oslo.serialization-2.13.0/requirements.txt      2016-08-10 
14:17:11.000000000 +0200
@@ -8,8 +8,7 @@
 # that is a likely indicator that the feature belongs somewhere else.
 
 pbr>=1.6 # Apache-2.0
-Babel>=1.3 # BSD
 six>=1.9.0 # MIT
 msgpack-python>=0.4.0 # Apache-2.0
-oslo.utils>=3.5.0 # Apache-2.0
+oslo.utils>=3.16.0 # Apache-2.0
 pytz>=2013.6 # MIT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.serialization-2.4.0/setup.cfg 
new/oslo.serialization-2.13.0/setup.cfg
--- old/oslo.serialization-2.4.0/setup.cfg      2016-02-25 07:07:39.000000000 
+0100
+++ new/oslo.serialization-2.13.0/setup.cfg     2016-08-10 14:18:40.000000000 
+0200
@@ -17,6 +17,7 @@
        Programming Language :: Python :: 2.7
        Programming Language :: Python :: 3
        Programming Language :: Python :: 3.4
+       Programming Language :: Python :: 3.5
 
 [files]
 packages = 
@@ -51,7 +52,7 @@
 universal = 1
 
 [egg_info]
-tag_svn_revision = 0
-tag_date = 0
 tag_build = 
+tag_date = 0
+tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.serialization-2.4.0/test-requirements.txt 
new/oslo.serialization-2.13.0/test-requirements.txt
--- old/oslo.serialization-2.4.0/test-requirements.txt  2016-02-25 
07:07:09.000000000 +0100
+++ new/oslo.serialization-2.13.0/test-requirements.txt 2016-08-10 
14:17:11.000000000 +0200
@@ -2,11 +2,12 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 hacking<0.11,>=0.10.0
-mock>=1.2 # BSD
+ipaddress>=1.0.7;python_version<'3.3' # PSF
+mock>=2.0 # BSD
 netaddr!=0.7.16,>=0.7.12 # BSD
 
 # this is required for the docs build jobs
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
 oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
 
 oslotest>=1.10.0 # Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.serialization-2.4.0/tox.ini 
new/oslo.serialization-2.13.0/tox.ini
--- old/oslo.serialization-2.4.0/tox.ini        2016-02-25 07:07:09.000000000 
+0100
+++ new/oslo.serialization-2.13.0/tox.ini       2016-08-10 14:17:11.000000000 
+0200
@@ -1,6 +1,6 @@
 [tox]
 minversion = 1.6
-envlist = py34,py27,pypy,pep8
+envlist = py35,py34,py27,pypy,pep8
 
 [testenv]
 deps = -r{toxinidir}/test-requirements.txt
@@ -19,12 +19,11 @@
 commands = python setup.py test --coverage 
--coverage-package-name=oslo_serialization --testr-args='{posargs}'
 
 [flake8]
-# H803 skipped on purpose per list discussion.
 # E123, E125 skipped as they are invalid PEP-8.
 
 show-source = True
-ignore = E123,E125,H803
-exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build
+ignore = E123,E125
+exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
 
 [testenv:pip-missing-reqs]
 # do not install test-requirements as that will pollute the virtualenv for


Reply via email to