Hello community,

here is the log from the commit of package python3-transaction for 
openSUSE:Factory checked in at 2016-11-22 18:59:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python3-transaction (Old)
 and      /work/SRC/openSUSE:Factory/.python3-transaction.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python3-transaction"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python3-transaction/python3-transaction.changes  
2016-11-17 12:44:26.000000000 +0100
+++ 
/work/SRC/openSUSE:Factory/.python3-transaction.new/python3-transaction.changes 
    2016-11-22 18:59:05.000000000 +0100
@@ -1,0 +2,11 @@
+Sun Nov 20 18:45:08 UTC 2016 - a...@gmx.de
+
+- update to version 2.0.3:
+  * The user and description fields must now be set with text
+    (unicode) data. Previously, if bytes were provided, they’d be
+    decoded as ASCII. It was decided that this would lead to bugs that
+    were hard to test for.
+  * Also, the transaction meta-data field, extended_info has been
+    renamed to extension.
+
+-------------------------------------------------------------------

Old:
----
  transaction-2.0.2.tar.gz

New:
----
  transaction-2.0.3.tar.gz

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

Other differences:
------------------
++++++ python3-transaction.spec ++++++
--- /var/tmp/diff_new_pack.gbReME/_old  2016-11-22 18:59:06.000000000 +0100
+++ /var/tmp/diff_new_pack.gbReME/_new  2016-11-22 18:59:06.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           python3-transaction
-Version:        2.0.2
+Version:        2.0.3
 Release:        0
 Summary:        Transaction management for Python
 License:        ZPL-2.1

++++++ transaction-2.0.2.tar.gz -> transaction-2.0.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/CHANGES.rst 
new/transaction-2.0.3/CHANGES.rst
--- old/transaction-2.0.2/CHANGES.rst   2016-11-13 22:11:02.000000000 +0100
+++ new/transaction-2.0.3/CHANGES.rst   2016-11-17 21:50:36.000000000 +0100
@@ -1,6 +1,17 @@
 Changes
 =======
 
+2.0.3 (2016-11-17)
+------------------
+
+- The user and description fields must now be set with text (unicode)
+  data.  Previously, if bytes were provided, they'd be decoded as
+  ASCII.  It was decided that this would lead to bugs that were hard
+  to test for.
+
+  Also, the transaction meta-data field, ``extended_info`` has been
+  renamed to ``extension``.
+
 2.0.2 (2016-11-13)
 ------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/PKG-INFO 
new/transaction-2.0.3/PKG-INFO
--- old/transaction-2.0.2/PKG-INFO      2016-11-13 22:12:15.000000000 +0100
+++ new/transaction-2.0.3/PKG-INFO      2016-11-17 21:51:31.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: transaction
-Version: 2.0.2
+Version: 2.0.3
 Summary: Transaction management for Python
 Home-page: https://github.com/zopefoundation/transaction
 Author: Zope Corporation
@@ -36,6 +36,17 @@
         Changes
         =======
         
+        2.0.3 (2016-11-17)
+        ------------------
+        
+        - The user and description fields must now be set with text (unicode)
+          data.  Previously, if bytes were provided, they'd be decoded as
+          ASCII.  It was decided that this would lead to bugs that were hard
+          to test for.
+        
+          Also, the transaction meta-data field, ``extended_info`` has been
+          renamed to ``extension``.
+        
         2.0.2 (2016-11-13)
         ------------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/docs/convenience.rst 
new/transaction-2.0.3/docs/convenience.rst
--- old/transaction-2.0.2/docs/convenience.rst  2016-11-11 23:13:48.000000000 
+0100
+++ new/transaction-2.0.3/docs/convenience.rst  2016-11-17 21:36:10.000000000 
+0100
@@ -23,7 +23,7 @@
 
     >>> with transaction.manager as t:
     ...     dm['z'] = 3
-    ...     t.note('test 3')
+    ...     t.note(u'test 3')
 
     >>> dm['z']
     3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/docs/convenience.rst~ 
new/transaction-2.0.3/docs/convenience.rst~
--- old/transaction-2.0.2/docs/convenience.rst~ 2016-11-11 21:26:05.000000000 
+0100
+++ new/transaction-2.0.3/docs/convenience.rst~ 2016-11-11 23:13:48.000000000 
+0100
@@ -28,8 +28,8 @@
     >>> dm['z']
     3
 
-    >>> dm.last_note
-    'test 3'
+    >>> dm.last_note == u'test 3'
+    True
 
     >>> with transaction.manager: #doctest ELLIPSIS
     ...     dm['z'] = 4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/setup.py 
new/transaction-2.0.3/setup.py
--- old/transaction-2.0.2/setup.py      2016-11-13 22:11:35.000000000 +0100
+++ new/transaction-2.0.3/setup.py      2016-11-17 21:51:01.000000000 +0100
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-version = '2.0.2'
+version = '2.0.3'
 
 import os
 from setuptools import setup, find_packages
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/t.py new/transaction-2.0.3/t.py
--- old/transaction-2.0.2/t.py  1970-01-01 01:00:00.000000000 +0100
+++ new/transaction-2.0.3/t.py  2016-11-16 20:16:04.000000000 +0100
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+
+def f():
+    """
+    doc ☯
+    """
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction/_compat.py~ 
new/transaction-2.0.3/transaction/_compat.py~
--- old/transaction-2.0.2/transaction/_compat.py~       1970-01-01 
01:00:00.000000000 +0100
+++ new/transaction-2.0.3/transaction/_compat.py~       2016-04-28 
20:29:54.000000000 +0200
@@ -0,0 +1,90 @@
+import sys
+import types
+
+PY3 = sys.version_info[0] == 3
+JYTHON = sys.platform.startswith('java')
+
+if PY3: # pragma: no cover
+    string_types = str,
+    integer_types = int,
+    class_types = type,
+    text_type = str
+    binary_type = bytes
+    long = int
+else:
+    string_types = basestring,
+    integer_types = (int, long)
+    class_types = (type, types.ClassType)
+    text_type = unicode
+    binary_type = str
+    long = long
+
+def bytes_(s, encoding='latin-1', errors='strict'): #pragma NO COVER
+    if isinstance(s, text_type):
+        return s.encode(encoding, errors)
+    return s
+
+if PY3: # pragma: no cover
+    def native_(s, encoding='latin-1', errors='strict'): #pragma NO COVER
+        if isinstance(s, text_type):
+            return s
+        return str(s, encoding, errors)
+else:
+    def native_(s, encoding='latin-1', errors='strict'): #pragma NO COVER
+        if isinstance(s, text_type):
+            return s.encode(encoding, errors)
+        return str(s)
+
+if PY3: #pragma NO COVER
+    from io import StringIO
+else:
+    from io import BytesIO as StringIO
+
+if PY3: #pragma NO COVER
+    from collections import MutableMapping
+else:
+    from UserDict import UserDict as MutableMapping
+
+if PY3: # pragma: no cover
+    import builtins
+    exec_ = getattr(builtins, "exec")
+
+
+    def reraise(tp, value, tb=None): #pragma NO COVER
+        if value.__traceback__ is not tb:
+            raise value.with_traceback(tb)
+        raise value
+
+else: # pragma: no cover
+    def exec_(code, globs=None, locs=None): #pragma NO COVER
+        """Execute code in a namespace."""
+        if globs is None:
+            frame = sys._getframe(1)
+            globs = frame.f_globals
+            if locs is None:
+                locs = frame.f_locals
+            del frame
+        elif locs is None:
+            locs = globs
+        exec("""exec code in globs, locs""")
+
+    exec_("""def reraise(tp, value, tb=None):
+    raise tp, value, tb
+""")
+
+
+if PY3: #pragma NO COVER
+    try:
+        from threading import get_ident as get_thread_ident
+    except ImportError:
+        from threading import _get_ident as get_thread_ident
+else:
+    from thread import get_ident as get_thread_ident
+
+
+if PY3:
+    def func_name(func): #pragma NO COVER
+        return func.__name__
+else:
+    def func_name(func): #pragma NO COVER
+        return func.func_name
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction/_manager.py 
new/transaction-2.0.3/transaction/_manager.py
--- old/transaction-2.0.2/transaction/_manager.py       2016-11-08 
18:55:06.000000000 +0100
+++ new/transaction-2.0.3/transaction/_manager.py       2016-11-17 
21:36:10.000000000 +0100
@@ -25,6 +25,7 @@
 from transaction.interfaces import TransientError
 from transaction.weakset import WeakSet
 from transaction._compat import reraise
+from transaction._compat import text_type
 from transaction._transaction import Transaction
 
 
@@ -178,6 +179,9 @@
             else:
                 doc = name
 
+        if doc and not isinstance(doc, text_type):
+            doc = doc.decode('utf-8')
+
         for i in range(1, tries + 1):
             txn = self.begin()
             if doc:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction/_manager.py~ 
new/transaction-2.0.3/transaction/_manager.py~
--- old/transaction-2.0.2/transaction/_manager.py~      2016-11-07 
19:32:33.000000000 +0100
+++ new/transaction-2.0.3/transaction/_manager.py~      2016-11-08 
18:55:06.000000000 +0100
@@ -146,7 +146,7 @@
             if number:
                 attempt = Attempt(self)
                 yield attempt
-                if attempt.sucess:
+                if attempt.success:
                     break
             else:
                 yield self
@@ -160,6 +160,42 @@
             if (should_retry is not None) and should_retry(error):
                 return True
 
+    run_no_func_types = int, type(None)
+    def run(self, func=None, tries=3):
+        if isinstance(func, self.run_no_func_types):
+            if func is not None:
+                tries = func
+            return lambda func: self.run(func, tries)
+
+        if tries <= 0:
+            raise ValueError("tries must be positive")
+
+        name = func.__name__
+        doc = func.__doc__
+        if name != '_':
+            if doc:
+                doc = name + '\n\n' + doc
+            else:
+                doc = name
+
+        for i in range(1, tries + 1):
+            txn = self.begin()
+            if doc:
+                txn.note(doc)
+
+            try:
+                result = func()
+                txn.commit()
+            except Exception as v:
+                if i == tries:
+                    raise # that was our last chance
+                retry = self._retryable(v.__class__, v)
+                txn.abort()
+                if not retry:
+                    raise
+            else:
+                return result
+
 
 class ThreadTransactionManager(TransactionManager, threading.local):
     """Thread-aware transaction manager.
@@ -170,7 +206,7 @@
 
 class Attempt(object):
 
-    sucess = False
+    success = False
 
     def __init__(self, manager):
         self.manager = manager
@@ -192,6 +228,6 @@
             except:
                 return self._retry_or_raise(*sys.exc_info())
             else:
-                self.sucess = True
+                self.success = True
         else:
             return self._retry_or_raise(t, v, tb)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction/_transaction.py 
new/transaction-2.0.3/transaction/_transaction.py
--- old/transaction-2.0.2/transaction/_transaction.py   2016-11-13 
22:05:52.000000000 +0100
+++ new/transaction-2.0.3/transaction/_transaction.py   2016-11-17 
21:50:07.000000000 +0100
@@ -27,6 +27,7 @@
 from transaction._compat import native_
 from transaction._compat import bytes_
 from transaction._compat import StringIO
+from transaction._compat import text_type
 
 _marker = object()
 
@@ -100,9 +101,9 @@
         # manager as a key, because we can't guess whether the actual
         # resource managers will be safe to use as dict keys.
 
-        # The user, description, and extended_info attributes are accessed
+        # The user, description, and extension attributes are accessed
         # directly by storages, leading underscore notwithstanding.
-        self.extended_info = {}
+        self.extension = {}
 
         self.log = _makeLogger()
         self.log.debug("new transaction")
@@ -122,11 +123,11 @@
     def _extension(self):
         # for backward compatibility, since most clients used this
         # absent any formal API.
-        return self.extended_info
+        return self.extension
 
     @_extension.setter
     def _extension(self, v):
-        self.extended_info = v
+        self.extension = v
 
     @property
     def user(self):
@@ -134,7 +135,9 @@
 
     @user.setter
     def user(self, v):
-        self._user = v + u'' # + u'' to make sure it's unicode
+        if not isinstance(v, text_type):
+            raise TypeError("User must be text (unicode)")
+        self._user = v
 
     @property
     def description(self):
@@ -142,7 +145,9 @@
 
     @description.setter
     def description(self, v):
-        self._description = v + u'' # + u'' to make sure it's unicode
+        if not isinstance(v, text_type):
+            raise TypeError("Description must be text (unicode)")
+        self._description = v
 
     def isDoomed(self):
         """ See ITransaction.
@@ -528,21 +533,28 @@
     def note(self, text):
         """ See ITransaction.
         """
+        if not isinstance(text, text_type):
+            raise TypeError("Note must be text (unicode)")
+
         text = text.strip()
         if self.description:
             self.description += u"\n" + text
         else:
             self.description = text
 
-    def setUser(self, user_name, path="/"):
+    def setUser(self, user_name, path=u"/"):
         """ See ITransaction.
         """
+        if not isinstance(user_name, text_type):
+            raise TypeError("User name must be text (unicode)")
+        if not isinstance(path, text_type):
+            raise TypeError("Path must be text (unicode)")
         self.user = u"%s %s" % (path, user_name)
 
     def setExtendedInfo(self, name, value):
         """ See ITransaction.
         """
-        self.extended_info[name + u''] = value # + u'' to make sure it's 
unicode
+        self.extension[name] = value
 
 
 # TODO: We need a better name for the adapters.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction/_transaction.py~ 
new/transaction-2.0.3/transaction/_transaction.py~
--- old/transaction-2.0.2/transaction/_transaction.py~  2016-11-11 
21:24:49.000000000 +0100
+++ new/transaction-2.0.3/transaction/_transaction.py~  2016-11-13 
22:05:52.000000000 +0100
@@ -124,6 +124,10 @@
         # absent any formal API.
         return self.extended_info
 
+    @_extension.setter
+    def _extension(self, v):
+        self.extended_info = v
+
     @property
     def user(self):
         return self._user
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction/interfaces.py 
new/transaction-2.0.3/transaction/interfaces.py
--- old/transaction-2.0.2/transaction/interfaces.py     2016-11-11 
21:24:49.000000000 +0100
+++ new/transaction-2.0.3/transaction/interfaces.py     2016-11-17 
21:50:07.000000000 +0100
@@ -125,12 +125,8 @@
         raise an exception, or truncate the value).
         """)
 
-    extended_info = Attribute(
-        """A dictionary containing application-defined metadata.
-
-        Keys must be text (unicode).  Values must be simple values
-        serializable with json or pickle (not instances).
-        """)
+    extension = Attribute(
+        "A dictionary containing application-defined metadata.")
 
     def commit():
         """Finalize the transaction.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction/interfaces.py~ 
new/transaction-2.0.3/transaction/interfaces.py~
--- old/transaction-2.0.2/transaction/interfaces.py~    2016-11-08 
18:55:06.000000000 +0100
+++ new/transaction-2.0.3/transaction/interfaces.py~    2016-11-11 
21:24:49.000000000 +0100
@@ -105,7 +105,7 @@
         """A user name associated with the transaction.
 
         The format of the user name is defined by the application.  The value
-        is of Python type str.  Storages record the user value, as meta-data,
+        is text (unicode).  Storages record the user value, as meta-data,
         when a transaction commits.
 
         A storage may impose a limit on the size of the value; behavior is
@@ -116,7 +116,7 @@
     description = Attribute(
         """A textual description of the transaction.
 
-        The value is of Python type str.  Method note() is the intended
+        The value is text (unicode).  Method note() is the intended
         way to set the value.  Storages record the description, as meta-data,
         when a transaction commits.
 
@@ -125,6 +125,13 @@
         raise an exception, or truncate the value).
         """)
 
+    extended_info = Attribute(
+        """A dictionary containing application-defined metadata.
+
+        Keys must be text (unicode).  Values must be simple values
+        serializable with json or pickle (not instances).
+        """)
+
     def commit():
         """Finalize the transaction.
 
@@ -167,7 +174,7 @@
         """
 
     def note(text):
-        """Add text to the transaction description.
+        """Add text (unicode) to the transaction description.
 
         This modifies the `.description` attribute; see its docs for more
         detail.  First surrounding whitespace is stripped from `text`.  If
@@ -176,21 +183,17 @@
         appended to `.description`.
         """
 
-    def setUser(user_name, path="/"):
-        """Set the user name.
-
-        path should be provided if needed to further qualify the
-        identified user.  This is a convenience method used by Zope.
-        It sets the .user attribute to str(path) + " " + str(user_name).
-        This sets the `.user` attribute; see its docs for more detail.
-        """
-
     def setExtendedInfo(name, value):
         """Add extension data to the transaction.
 
-        name is the name of the extension property to set, of Python type
-        str; value must be picklable.  Multiple calls may be made to set
-        multiple extension properties, provided the names are distinct.
+        name
+          is the text (unicode) name of the extension property to set
+
+        value
+          must be picklable and json serializable (not an instance).
+
+        Multiple calls may be made to set multiple extension
+        properties, provided the names are distinct.
 
         Storages record the extension data, as meta-data, when a transaction
         commits.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transaction-2.0.2/transaction/tests/test__transaction.py 
new/transaction-2.0.3/transaction/tests/test__transaction.py
--- old/transaction-2.0.2/transaction/tests/test__transaction.py        
2016-11-13 22:05:52.000000000 +0100
+++ new/transaction-2.0.3/transaction/tests/test__transaction.py        
2016-11-17 21:50:07.000000000 +0100
@@ -76,8 +76,8 @@
         self.assertEqual(txn._resources, [])
         self.assertEqual(txn._adapters, {})
         self.assertEqual(txn._voted, {})
-        self.assertEqual(txn.extended_info, {})
-        self.assertTrue(txn._extension is txn.extended_info) # legacy
+        self.assertEqual(txn.extension, {})
+        self.assertTrue(txn._extension is txn.extension) # legacy
         self.assertTrue(txn.log is logger)
         self.assertEqual(len(logger._log), 1)
         self.assertEqual(logger._log[0][0], 'debug')
@@ -983,37 +983,43 @@
     def test_note(self):
         txn = self._makeOne()
         try:
-            txn.note('This is a note.')
+            txn.note(u'This is a note.')
             self.assertEqual(txn.description, u'This is a note.')
-            txn.note('Another.')
+            txn.note(u'Another.')
             self.assertEqual(txn.description, u'This is a note.\nAnother.')
         finally:
             txn.abort()
 
-    def test_description_nonascii_bytes(self):
+    def test_description_bytes(self):
         txn = self._makeOne()
-        with self.assertRaises((UnicodeDecodeError, TypeError)):
-            txn.description = b'\xc2\x80'
+        with self.assertRaises(TypeError):
+            txn.description = b'haha'
 
     def test_setUser_default_path(self):
         txn = self._makeOne()
-        txn.setUser('phreddy')
+        txn.setUser(u'phreddy')
         self.assertEqual(txn.user, u'/ phreddy')
 
     def test_setUser_explicit_path(self):
         txn = self._makeOne()
-        txn.setUser('phreddy', '/bedrock')
+        txn.setUser(u'phreddy', u'/bedrock')
         self.assertEqual(txn.user, u'/bedrock phreddy')
 
-    def test_user_nonascii_bytes(self):
+    def test_user_bytes(self):
         txn = self._makeOne()
-        with self.assertRaises((UnicodeDecodeError, TypeError)):
-            txn.user = b'\xc2\x80'
+        with self.assertRaises(TypeError):
+            txn.user = b'phreddy'
+        with self.assertRaises(TypeError):
+            txn.setUser(b'phreddy', u'/bedrock')
+        with self.assertRaises(TypeError):
+            txn.setUser(u'phreddy', b'/bedrock')
+        with self.assertRaises(TypeError):
+            txn.setUser(b'phreddy')
 
     def test_setExtendedInfo_single(self):
         txn = self._makeOne()
         txn.setExtendedInfo('frob', 'qux')
-        self.assertEqual(txn.extended_info, {u'frob': 'qux'})
+        self.assertEqual(txn.extension, {u'frob': 'qux'})
         self.assertTrue(txn._extension is txn._extension) # legacy
 
     def test_setExtendedInfo_multiple(self):
@@ -1029,7 +1035,7 @@
         txn = self._makeOne()
         txn._extension = dict(baz='spam')
         txn.setExtendedInfo('frob', 'qux')
-        self.assertEqual(txn.extended_info, {u'frob': 'qux', 'baz': 'spam'})
+        self.assertEqual(txn.extension, {u'frob': 'qux', 'baz': 'spam'})
 
     def test_data(self):
         txn = self._makeOne()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transaction-2.0.2/transaction/tests/test__transaction.py~ 
new/transaction-2.0.3/transaction/tests/test__transaction.py~
--- old/transaction-2.0.2/transaction/tests/test__transaction.py~       
2016-11-11 21:24:49.000000000 +0100
+++ new/transaction-2.0.3/transaction/tests/test__transaction.py~       
2016-11-13 22:05:52.000000000 +0100
@@ -1024,6 +1024,13 @@
         self.assertEqual(txn._extension, {u'frob': 'quxxxx', u'baz': 'spam'})
         self.assertTrue(txn._extension is txn._extension) # legacy
 
+    def test__extension_settable(self):
+        # Because ZEO sets it. I'll fix ZEO, but maybe something else will 
break
+        txn = self._makeOne()
+        txn._extension = dict(baz='spam')
+        txn.setExtendedInfo('frob', 'qux')
+        self.assertEqual(txn.extended_info, {u'frob': 'qux', 'baz': 'spam'})
+
     def test_data(self):
         txn = self._makeOne()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction.egg-info/PKG-INFO 
new/transaction-2.0.3/transaction.egg-info/PKG-INFO
--- old/transaction-2.0.2/transaction.egg-info/PKG-INFO 2016-11-13 
22:12:13.000000000 +0100
+++ new/transaction-2.0.3/transaction.egg-info/PKG-INFO 2016-11-17 
21:51:29.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: transaction
-Version: 2.0.2
+Version: 2.0.3
 Summary: Transaction management for Python
 Home-page: https://github.com/zopefoundation/transaction
 Author: Zope Corporation
@@ -36,6 +36,17 @@
         Changes
         =======
         
+        2.0.3 (2016-11-17)
+        ------------------
+        
+        - The user and description fields must now be set with text (unicode)
+          data.  Previously, if bytes were provided, they'd be decoded as
+          ASCII.  It was decided that this would lead to bugs that were hard
+          to test for.
+        
+          Also, the transaction meta-data field, ``extended_info`` has been
+          renamed to ``extension``.
+        
         2.0.2 (2016-11-13)
         ------------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transaction-2.0.2/transaction.egg-info/SOURCES.txt 
new/transaction-2.0.3/transaction.egg-info/SOURCES.txt
--- old/transaction-2.0.2/transaction.egg-info/SOURCES.txt      2016-11-13 
22:12:15.000000000 +0100
+++ new/transaction-2.0.3/transaction.egg-info/SOURCES.txt      2016-11-17 
21:51:31.000000000 +0100
@@ -10,6 +10,7 @@
 rtd.txt
 setup.cfg
 setup.py
+t.py
 tox.ini
 docs/Makefile
 docs/Makefile~
@@ -31,6 +32,7 @@
 docs/_templates/placeholder.txt
 transaction/__init__.py
 transaction/_compat.py
+transaction/_compat.py~
 transaction/_manager.py
 transaction/_manager.py~
 transaction/_transaction.py


Reply via email to