Hello community,

here is the log from the commit of package python-ZODB for openSUSE:Factory 
checked in at 2019-03-05 12:24:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ZODB (Old)
 and      /work/SRC/openSUSE:Factory/.python-ZODB.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ZODB"

Tue Mar  5 12:24:42 2019 rev:7 rq:681509 version:5.5.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-ZODB/python-ZODB.changes  2018-07-27 
10:58:10.837869149 +0200
+++ /work/SRC/openSUSE:Factory/.python-ZODB.new.28833/python-ZODB.changes       
2019-03-05 12:24:46.252851511 +0100
@@ -1,0 +2,12 @@
+Mon Mar  4 14:15:53 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 5.5.1:
+  * Add support for Python 3.7.
+  * Bump the dependency on zodbpickle to at least 1.0.1. This is required to 
avoid a memory leak on Python 2.7. See issue 203.
+  * Bump the dependency on persistent to at least 4.4.0.
+  * Make the internal support functions for dealing with OIDs (p64 and u64) 
somewhat faster and raise more informative exceptions on certain types of bad 
input. See issue 216.
+  * Remove support for python setup.py test. It hadn't been working for some 
time. See issue #218.
+  * Make the tests run faster by avoiding calls to time.sleep().
+- Drop no longer needed python-ZODB-testsuite.patch
+
+-------------------------------------------------------------------

Old:
----
  ZODB-5.4.0.tar.gz
  python-ZODB-testsuite.patch

New:
----
  ZODB-5.5.1.tar.gz

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

Other differences:
------------------
++++++ python-ZODB.spec ++++++
--- /var/tmp/diff_new_pack.ay4OyY/_old  2019-03-05 12:24:47.632851090 +0100
+++ /var/tmp/diff_new_pack.ay4OyY/_new  2019-03-05 12:24:47.632851090 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-ZODB
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 # Copyright (c) 2013 LISA GmbH, Bingen, Germany.
 #
 # All modifications and additions to the file contributed by third parties
@@ -13,27 +13,27 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-ZODB
-Version:        5.4.0
+Version:        5.5.1
 Release:        0
 Summary:        Zope Object Database: object database and persistence
 License:        ZPL-2.1
 Group:          Development/Libraries/Python
-URL:            http://www.zodb.org/
+URL:            https://github.com/zopefoundation/ZODB
 Source:         
https://files.pythonhosted.org/packages/source/Z/ZODB/ZODB-%{version}.tar.gz
-Patch0:         python-ZODB-testsuite.patch
 BuildRequires:  %{python_module BTrees >= 4.2.0}
 BuildRequires:  %{python_module ZConfig}
 BuildRequires:  %{python_module manuel}
-BuildRequires:  %{python_module persistent-devel >= 4.2.0}
+BuildRequires:  %{python_module mock}
+BuildRequires:  %{python_module persistent-devel >= 4.4.0}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  %{python_module six}
-BuildRequires:  %{python_module transaction >= 2.0.3}
+BuildRequires:  %{python_module transaction >= 2.4.0}
 BuildRequires:  %{python_module zc.lockfile}
 BuildRequires:  %{python_module zodbpickle >= 1.0.1}
 BuildRequires:  %{python_module zope.interface}
@@ -43,9 +43,9 @@
 BuildRequires:  python-rpm-macros
 Requires:       python-BTrees >= 4.2.0
 Requires:       python-ZConfig
-Requires:       python-persistent >= 4.2.0
+Requires:       python-persistent >= 4.4.0
 Requires:       python-six
-Requires:       python-transaction >= 2.0.3
+Requires:       python-transaction >= 2.4.0
 Requires:       python-zc.lockfile
 Requires:       python-zodbpickle >= 1.0.1
 Requires:       python-zope.interface
@@ -76,14 +76,15 @@
 # remove unwanted shebang
 find src -name "*.py" | xargs sed -i '1 { /^#!/ d }'
 rm -rf src/ZODB.egg-info
-%patch0 -p1
+# do not test docu generating
+rm -f src/ZODB/tests/testdocumentation.py
 
 %build
 %python_build
 
 %install
 %python_install
-%python_expand %fdupes -s %{buildroot}%{$python_sitelib}
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %python_clone -a %{buildroot}%{_bindir}/fsdump
 %python_clone -a %{buildroot}%{_bindir}/fsoids
@@ -92,7 +93,7 @@
 %python_clone -a %{buildroot}%{_bindir}/repozo
 
 %check
-#%%python_exec setup.py test
+%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} 
zope-testrunner-%{$python_bin_suffix} --test-path=src
 
 %post
 %python_install_alternative fsdump fsoids fsrefs fstail repozo

++++++ ZODB-5.4.0.tar.gz -> ZODB-5.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/CHANGES.rst new/ZODB-5.5.1/CHANGES.rst
--- old/ZODB-5.4.0/CHANGES.rst  2018-03-26 15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/CHANGES.rst  2018-10-25 17:52:17.000000000 +0200
@@ -2,6 +2,35 @@
  Change History
 ================
 
+5.5.1 (2018-10-25)
+==================
+
+- Fix KeyError on releasing resources of a Connection when closing the DB.
+  This requires at least version 2.4 of the `transaction` package.
+  See `issue 208 <https://github.com/zopefoundation/ZODB/issues/208>`.
+
+5.5.0 (2018-10-13)
+==================
+
+- Add support for Python 3.7.
+
+- Bump the dependency on zodbpickle to at least 1.0.1. This is
+  required to avoid a memory leak on Python 2.7. See `issue 203
+  <https://github.com/zopefoundation/ZODB/issues/203>`_.
+
+- Bump the dependency on persistent to at least 4.4.0.
+
+- Make the internal support functions for dealing with OIDs (``p64``
+  and ``u64``) somewhat faster and raise more informative
+  exceptions on certain types of bad input. See `issue 216
+  <https://github.com/zopefoundation/ZODB/issues/216>`_.
+
+- Remove support for ``python setup.py test``. It hadn't been working
+  for some time. See `issue #218
+  <https://github.com/zopefoundation/ZODB/issues/218>`_.
+
+- Make the tests run faster by avoiding calls to ``time.sleep()``.
+
 5.4.0 (2018-03-26)
 ==================
 
@@ -42,10 +71,10 @@
   cost of being very slightly less efficient for old-style classes.
 
   .. note:: On Python 2, this will now allow open ``file`` objects
-                       (but **not** open blobs or sockets) to be pickled 
(loading
-                       the object will result in a closed file); previously 
this
-                       would result in a ``TypeError``. Doing so is not
-                       recommended as they cannot be loaded in Python 3.
+            (but **not** open blobs or sockets) to be pickled (loading
+            the object will result in a closed file); previously this
+            would result in a ``TypeError``. Doing so is not
+            recommended as they cannot be loaded in Python 3.
 
   See `issue 179 <https://github.com/zopefoundation/ZODB/pull/179>`_.
 
@@ -145,7 +174,7 @@
 Major internal improvements and cleanups plus:
 
 - Added a connection ``prefetch`` method that can be used to request
-  that a storage prefect data an application will need::
+  that a storage prefetch data an application will need::
 
     conn.prefetch(obj, ...)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/PKG-INFO new/ZODB-5.5.1/PKG-INFO
--- old/ZODB-5.4.0/PKG-INFO     2018-03-26 15:29:03.000000000 +0200
+++ new/ZODB-5.5.1/PKG-INFO     2018-10-25 17:52:53.000000000 +0200
@@ -1,10 +1,12 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
 Name: ZODB
-Version: 5.4.0
+Version: 5.5.1
 Summary: ZODB, a Python object-oriented database
 Home-page: http://www.zodb.org/
-Author: Zope Foundation and Contributors
-Author-email: [email protected]
+Author: Jim Fulton
+Author-email: [email protected]
+Maintainer: Zope Foundation and Contributors
+Maintainer-email: [email protected]
 License: ZPL 2.1
 Description: =======================================
         ZODB, a Python object-oriented database
@@ -60,6 +62,35 @@
          Change History
         ================
         
+        5.5.1 (2018-10-25)
+        ==================
+        
+        - Fix KeyError on releasing resources of a Connection when closing the 
DB.
+          This requires at least version 2.4 of the `transaction` package.
+          See `issue 208 <https://github.com/zopefoundation/ZODB/issues/208>`.
+        
+        5.5.0 (2018-10-13)
+        ==================
+        
+        - Add support for Python 3.7.
+        
+        - Bump the dependency on zodbpickle to at least 1.0.1. This is
+          required to avoid a memory leak on Python 2.7. See `issue 203
+          <https://github.com/zopefoundation/ZODB/issues/203>`_.
+        
+        - Bump the dependency on persistent to at least 4.4.0.
+        
+        - Make the internal support functions for dealing with OIDs (``p64``
+          and ``u64``) somewhat faster and raise more informative
+          exceptions on certain types of bad input. See `issue 216
+          <https://github.com/zopefoundation/ZODB/issues/216>`_.
+        
+        - Remove support for ``python setup.py test``. It hadn't been working
+          for some time. See `issue #218
+          <https://github.com/zopefoundation/ZODB/issues/218>`_.
+        
+        - Make the tests run faster by avoiding calls to ``time.sleep()``.
+        
         5.4.0 (2018-03-26)
         ==================
         
@@ -100,10 +131,10 @@
           cost of being very slightly less efficient for old-style classes.
         
           .. note:: On Python 2, this will now allow open ``file`` objects
-                               (but **not** open blobs or sockets) to be 
pickled (loading
-                               the object will result in a closed file); 
previously this
-                               would result in a ``TypeError``. Doing so is not
-                               recommended as they cannot be loaded in Python 
3.
+                    (but **not** open blobs or sockets) to be pickled (loading
+                    the object will result in a closed file); previously this
+                    would result in a ``TypeError``. Doing so is not
+                    recommended as they cannot be loaded in Python 3.
         
           See `issue 179 <https://github.com/zopefoundation/ZODB/pull/179>`_.
         
@@ -203,7 +234,7 @@
         Major internal improvements and cleanups plus:
         
         - Added a connection ``prefetch`` method that can be used to request
-          that a storage prefect data an application will need::
+          that a storage prefetch data an application will need::
         
             conn.prefetch(obj, ...)
         
@@ -540,6 +571,7 @@
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Database
@@ -548,3 +580,4 @@
 Classifier: Operating System :: Unix
 Classifier: Framework :: ZODB
 Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
+Provides-Extra: test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/doc/index.rst new/ZODB-5.5.1/doc/index.rst
--- old/ZODB-5.4.0/doc/index.rst        2018-03-26 15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/doc/index.rst        2018-10-13 18:58:14.000000000 +0200
@@ -141,7 +141,7 @@
   enough to support some search.
 
 You read data a lot more than you write it.
-  ZODB caches aggressively, and if you're working set fits (or mostly
+  ZODB caches aggressively, and if your working set fits (or mostly
   fits) in memory, performance is very good because it rarely has to
   touch the database server.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/setup.py new/ZODB-5.5.1/setup.py
--- old/ZODB-5.4.0/setup.py     2018-03-26 15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/setup.py     2018-10-25 17:52:17.000000000 +0200
@@ -11,10 +11,9 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-import os
 from setuptools import setup, find_packages
 
-version = '5.4.0'
+version = '5.5.1'
 
 classifiers = """\
 Intended Audience :: Developers
@@ -26,6 +25,7 @@
 Programming Language :: Python :: 3.4
 Programming Language :: Python :: 3.5
 Programming Language :: Python :: 3.6
+Programming Language :: Python :: 3.7
 Programming Language :: Python :: Implementation :: CPython
 Programming Language :: Python :: Implementation :: PyPy
 Topic :: Database
@@ -35,62 +35,6 @@
 Framework :: ZODB
 """
 
-def _modname(path, base, name=''):
-    if path == base:
-        return name
-    dirname, basename = os.path.split(path)
-    return _modname(dirname, base, basename + '.' + name)
-
-def _flatten(suite, predicate=lambda *x: True):
-    from unittest import TestCase
-    for suite_or_case in suite:
-        if predicate(suite_or_case):
-            if isinstance(suite_or_case, TestCase):
-                yield suite_or_case
-            else:
-                for x in _flatten(suite_or_case):
-                    yield x
-
-def _no_layer(suite_or_case):
-    return getattr(suite_or_case, 'layer', None) is None
-
-def _unittests_only(suite, mod_suite):
-    for case in _flatten(mod_suite, _no_layer):
-        suite.addTest(case)
-
-def alltests():
-    import logging
-    import pkg_resources
-    import unittest
-
-    # Something wacked in setting recursion limit when running setup test
-    import ZODB.FileStorage.tests
-    del ZODB.FileStorage.tests._save_index
-
-    class NullHandler(logging.Handler):
-        level = 50
-
-        def emit(self, record):
-            pass
-
-    logging.getLogger().addHandler(NullHandler())
-
-    suite = unittest.TestSuite()
-    base = pkg_resources.working_set.find(
-        pkg_resources.Requirement.parse('ZODB')).location
-    for dirpath, _dirnames, filenames in os.walk(base):
-        if os.path.basename(dirpath) == 'tests':
-            for filename in filenames:
-                if filename.endswith('.py') and filename.startswith('test'):
-                    mod = __import__(
-                        _modname(dirpath, base, os.path.splitext(filename)[0]),
-                        {}, {}, ['*'])
-                    _unittests_only(suite, mod.test_suite())
-        elif 'tests.py' in filenames:
-            mod = __import__(_modname(dirpath, base, 'tests'), {}, {}, ['*'])
-            _unittests_only(suite, mod.test_suite())
-    return suite
-
 def read(path):
     with open(path) as f:
         return f.read()
@@ -99,6 +43,7 @@
 
 tests_require = [
     'manuel',
+    'mock; python_version == "2.7"',
     'zope.testing',
     'zope.testrunner >= 4.4.6',
 ]
@@ -119,20 +64,19 @@
     classifiers=list(filter(None, classifiers.split("\n"))),
     description=long_description.split('\n', 2)[1],
     long_description=long_description,
-    test_suite="__main__.alltests", # to support "setup.py test"
     tests_require=tests_require,
     extras_require={
         'test': tests_require,
     },
     install_requires=[
-        'persistent >= 4.2.0',
+        'persistent >= 4.4.0',
         'BTrees >= 4.2.0',
         'ZConfig',
-        'transaction >= 2.0.3',
+        'transaction >= 2.4',
         'six',
         'zc.lockfile',
         'zope.interface',
-        'zodbpickle >= 0.6.0',
+        'zodbpickle >= 1.0.1',
     ],
     zip_safe=False,
     entry_points="""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/Connection.py 
new/ZODB-5.5.1/src/ZODB/Connection.py
--- old/ZODB-5.4.0/src/ZODB/Connection.py       2018-03-26 15:29:02.000000000 
+0200
+++ new/ZODB-5.5.1/src/ZODB/Connection.py       2018-10-25 17:30:38.000000000 
+0200
@@ -884,7 +884,10 @@
         """
 
         if transaction_manager is None:
-            transaction_manager = transaction.manager
+            # The .manager bit below unwraps the threaded
+            # manager so we can call unregisterSynch in close
+            # when close is called from another thread.
+            transaction_manager = transaction.manager.manager
 
         self.transaction_manager = transaction_manager
 
@@ -1328,7 +1331,7 @@
     @property
     def _extension(self):
         warnings.warn("_extension is deprecated, use extension",
-                      DeprecationWarning)
+                      DeprecationWarning, stacklevel=2)
         return self.extension
 
     @_extension.setter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/MappingStorage.py 
new/ZODB-5.5.1/src/ZODB/MappingStorage.py
--- old/ZODB-5.4.0/src/ZODB/MappingStorage.py   2018-03-26 15:29:02.000000000 
+0200
+++ new/ZODB-5.5.1/src/ZODB/MappingStorage.py   2018-08-31 19:05:22.000000000 
+0200
@@ -344,8 +344,8 @@
         self.extension = extension
         self.data = data
 
-    _extension = property(lambda self: self._extension,
-                          lambda self, v: setattr(self, '_extension', v),
+    _extension = property(lambda self: self.extension,
+                          lambda self, v: setattr(self, 'extension', v),
                           )
 
     def __iter__(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/scripts/analyze.py 
new/ZODB-5.5.1/src/ZODB/scripts/analyze.py
--- old/ZODB-5.4.0/src/ZODB/scripts/analyze.py  2018-03-26 15:29:02.000000000 
+0200
+++ new/ZODB-5.5.1/src/ZODB/scripts/analyze.py  2018-08-31 19:06:03.000000000 
+0200
@@ -67,8 +67,7 @@
     fmts = "%46s %7d %8dk %5.1f%% %7.2f" # summary format
     print(fmt % ("Class Name", "Count", "TBytes", "Pct", "AvgSize"))
     print(fmt % ('-'*46, '-'*7, '-'*9, '-'*5, '-'*7))
-    typemap = rep.TYPEMAP.keys()
-    typemap.sort()
+    typemap = sorted(rep.TYPEMAP)
     cumpct = 0.0
     for t in typemap:
         pct = rep.TYPESIZE[t] * 100.0 / rep.DBYTES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/scripts/tests/test_doc.py 
new/ZODB-5.5.1/src/ZODB/scripts/tests/test_doc.py
--- old/ZODB-5.4.0/src/ZODB/scripts/tests/test_doc.py   2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/scripts/tests/test_doc.py   2018-08-31 
19:05:22.000000000 +0200
@@ -19,7 +19,7 @@
 
 checker = zope.testing.renormalizing.RENormalizing([
     (re.compile(
-        '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+'),
+        r'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+'),
      '2007-11-10 15:18:48.543001'),
     (re.compile('hash=[0-9a-f]{40}'),
      'hash=b16422d09fabdb45d4e4325e4b42d7d6f021d3c3'),
@@ -29,13 +29,13 @@
     # Python 3 produces larger pickles, even when we use zodbpickle :(
     # this changes all the offsets and sizes in fstail.txt
     (re.compile("user='' description='' "
-                    "length=[0-9]+ offset=[0-9]+ \(\+23\)"),
-                "user='' description='' "
-                    "length=<LENGTH> offset=<OFFSET> (+23)"),
+                r"length=[0-9]+ offset=[0-9]+ \(\+23\)"),
+     "user='' description='' "
+     "length=<LENGTH> offset=<OFFSET> (+23)"),
     (re.compile("user='' description='initial database creation' "
-                    "length=[0-9]+ offset=4 \(\+48\)"),
-                "user='' description='initial database creation' "
-                    "length=<LENGTH> offset=4 (+48)"),
+                r"length=[0-9]+ offset=4 \(\+48\)"),
+     "user='' description='initial database creation' "
+     "length=<LENGTH> offset=4 (+48)"),
 ])
 
 def test_suite():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/scripts/tests/test_repozo.py 
new/ZODB-5.5.1/src/ZODB/scripts/tests/test_repozo.py
--- old/ZODB-5.4.0/src/ZODB/scripts/tests/test_repozo.py        2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/scripts/tests/test_repozo.py        2018-10-13 
19:13:58.000000000 +0200
@@ -19,11 +19,11 @@
 
 import ZODB.tests.util  # layer used at class scope
 
-try:
-    from StringIO import StringIO
-    BytesIO = StringIO
-except ImportError:
-    from io import BytesIO, StringIO
+from io import BytesIO, StringIO
+if str is bytes:
+    NativeStringIO = BytesIO
+else:
+    NativeStringIO = StringIO
 
 
 _NOISY = os.environ.get('NOISY_REPOZO_TEST_OUTPUT')
@@ -94,19 +94,12 @@
 
 class Test_parseargs(unittest.TestCase):
 
-    # Python 2.6 lacks this
-    def assertIn(self, member, container, msg=None):
-        if member not in container:
-            standardMsg = '%s not found in %s' % (repr(member),
-                                                  repr(container))
-            self.fail(self._formatMessage(msg, standardMsg))
-
     def setUp(self):
         from ZODB.scripts import repozo
         self._old_verbosity = repozo.VERBOSE
         self._old_stderr = sys.stderr
         repozo.VERBOSE = False
-        sys.stderr = StringIO()
+        sys.stderr = NativeStringIO()
 
     def tearDown(self):
         from ZODB.scripts import repozo
@@ -134,7 +127,7 @@
         # zope.testrunner will happily print the traceback and failure message
         # into our StringIO before running our tearDown.
         old_stdout = sys.stdout
-        sys.stdout = StringIO()
+        sys.stdout = NativeStringIO()
         try:
             self.assertRaises(SystemExit, repozo.parseargs, ['--help'])
             self.assertIn('Usage:', sys.stdout.getvalue())
@@ -1099,6 +1092,7 @@
         from ZODB.scripts.repozo import main
         main(argv)
 
+    @ZODB.tests.util.time_monotonically_increases
     def test_via_monte_carlo(self):
         self.saved_snapshots = []  # list of (name, time) pairs for copies.
 
@@ -1142,8 +1136,7 @@
             copyfile(srcname, copyname)
             self.saved_snapshots.append((copyname, copytime))
 
-        # Make sure the clock moves at least a second.
-        sleep(1.01)
+        # The clock moves forward automatically on calls to time.time()
 
         # Verify current Data.fs can be reproduced exactly.
         self.assertRestored()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/PackableStorage.py 
new/ZODB-5.5.1/src/ZODB/tests/PackableStorage.py
--- old/ZODB-5.4.0/src/ZODB/tests/PackableStorage.py    2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/tests/PackableStorage.py    2018-10-13 
19:13:58.000000000 +0200
@@ -30,6 +30,7 @@
 import transaction
 import ZODB.interfaces
 import ZODB.tests.util
+from ZODB.tests.util import time_monotonically_increases
 import zope.testing.setupstack
 
 from ZODB.utils import load_current
@@ -274,12 +275,15 @@
 
         db.close()
 
+    @time_monotonically_increases
     def checkPackWhileWriting(self):
         self._PackWhileWriting(pack_now=False)
 
+    @time_monotonically_increases
     def checkPackNowWhileWriting(self):
         self._PackWhileWriting(pack_now=True)
 
+    @time_monotonically_increases
     def checkPackLotsWhileWriting(self):
         # This is like the other pack-while-writing tests, except it packs
         # repeatedly until the client thread is done.  At the time it was
@@ -608,6 +612,7 @@
 
         eq(root['obj'].value, 7)
 
+    @time_monotonically_increases
     def checkRedundantPack(self):
         # It is an error to perform a pack with a packtime earlier
         # than a previous packtime.  The storage can't do a full
@@ -652,6 +657,7 @@
         # it is reachable.
         load_current(self._storage, lost_oid)
 
+    @time_monotonically_increases(0.1)
     def checkPackUndoLog(self):
         self._initroot()
         # Create a `persistent' object
@@ -669,7 +675,7 @@
         self.assertEqual(3, len(self._storage.undoLog()))
         self._storage.pack(packtime, referencesf)
         # The undo log contains only the most resent transaction
-        self.assertEqual(1,len(self._storage.undoLog()))
+        self.assertEqual(1, len(self._storage.undoLog()))
 
     def dont_checkPackUndoLogUndoable(self):
         # A disabled test. I wanted to test that the content of the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/RecoveryStorage.py 
new/ZODB-5.5.1/src/ZODB/tests/RecoveryStorage.py
--- old/ZODB-5.4.0/src/ZODB/tests/RecoveryStorage.py    2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/tests/RecoveryStorage.py    2018-10-13 
19:13:58.000000000 +0200
@@ -21,6 +21,7 @@
 from ZODB.serialize import referencesf
 
 from ZODB.utils import load_current
+from ZODB.tests.util import time_monotonically_increases
 
 import time
 
@@ -66,6 +67,7 @@
         self._dst.tpc_vote(final)
         self._dst.tpc_finish(final)
 
+    @time_monotonically_increases
     def checkPackWithGCOnDestinationAfterRestore(self):
         raises = self.assertRaises
         db = DB(self._storage)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/RevisionStorage.py 
new/ZODB-5.5.1/src/ZODB/tests/RevisionStorage.py
--- old/ZODB-5.4.0/src/ZODB/tests/RevisionStorage.py    2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/tests/RevisionStorage.py    2018-10-13 
19:13:58.000000000 +0200
@@ -17,6 +17,7 @@
 from ZODB.tests.MinPO import MinPO
 from ZODB.tests.StorageTestBase import zodb_unpickle, zodb_pickle, snooze
 from ZODB.utils import p64, u64, load_current
+from ZODB.tests.util import time_monotonically_increases
 
 ZERO = '\0'*8
 
@@ -34,6 +35,7 @@
             data = self._storage.loadSerial(oid, revid)
             self.assertEqual(zodb_unpickle(data), value)
 
+    @time_monotonically_increases
     def checkLoadBefore(self):
         # Store 10 revisions of one object and then make sure that we
         # can get all the non-current revisions back.
@@ -89,6 +91,7 @@
         self.assertEqual(start, revid1)
         self.assertEqual(end, revid2)
 
+    @time_monotonically_increases
     def checkLoadBeforeOld(self):
         # Look for a very old revision.  With the BaseStorage implementation
         # this should require multple history() calls.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/synchronizers.txt 
new/ZODB-5.5.1/src/ZODB/tests/synchronizers.txt
--- old/ZODB-5.4.0/src/ZODB/tests/synchronizers.txt     2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/tests/synchronizers.txt     2018-08-31 
19:05:22.000000000 +0200
@@ -26,7 +26,7 @@
     >>> rt = cn.root()
     >>> rt['a'] = 1
 
-Sync isn't called when a connectiin is opened, even though that
+Sync isn't called when a connection is opened, even though that
 implicitly starts a new transaction:
 
     >>> st.sync_called
@@ -40,7 +40,7 @@
     True
     >>> st.sync_called = False
 
-BTW, calling ``sync()`` on a connectin starts a new transaction, which
+BTW, calling ``sync()`` on a connection starts a new transaction, which
 caused ``sync()`` to be called on the storage:
 
     >>> cn.sync()
@@ -49,7 +49,7 @@
     >>> st.sync_called = False
 
 ``sync()`` is not called by the Connection's ``afterCompletion()``
-hook after the commit completes, because we'll sunc when a new
+hook after the commit completes, because we'll sync when a new
 transaction begins:
 
     >>> transaction.commit()
@@ -81,7 +81,7 @@
     >>> cn.close()
 
 As a special case, if a synchronizer registers while a transaction is
-in flight, then newTransaction and this the storage sync method is
+in flight, then newTransaction and thus the storage sync method is
 called:
 
     >>> tm = transaction.TransactionManager()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/testCache.py 
new/ZODB-5.5.1/src/ZODB/tests/testCache.py
--- old/ZODB-5.4.0/src/ZODB/tests/testCache.py  2018-03-26 15:29:02.000000000 
+0200
+++ new/ZODB-5.5.1/src/ZODB/tests/testCache.py  2018-10-13 19:13:58.000000000 
+0200
@@ -378,7 +378,12 @@
             # structure that adds a new reference to None for each executed
             # line of code, which interferes with this test.  So check it
             # only if we're running without coverage tracing.
-            self.assertEqual(rc(None), nones)
+
+            # On Python 3.7, we can see the value of reference counts
+            # to None actually go *down* by a few. Possibly it has to
+            # do with the lazy tracking of frames?
+            # 
(https://github.com/python/cpython/commit/5a625d0aa6a6d9ec6574ee8344b41d63dcb9897e)
+            self.assertLessEqual(rc(None), nones)
 
     def testTwoCaches(self):
         jar2 = StubDataManager()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/testConnection.py 
new/ZODB-5.5.1/src/ZODB/tests/testConnection.py
--- old/ZODB-5.4.0/src/ZODB/tests/testConnection.py     2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/tests/testConnection.py     2018-08-31 
19:05:22.000000000 +0200
@@ -36,7 +36,7 @@
     # Python 3 bytes add a "b".
     (re.compile("b('.*?')"), r"\1"),
     # Python 3 removes empty list representation.
-    (re.compile("set\(\[\]\)"), r"set()"),
+    (re.compile(r"set\(\[\]\)"), r"set()"),
     # Python 3 adds module name to exceptions.
     (re.compile("ZODB.POSException.POSKeyError"), r"POSKeyError"),
     (re.compile("ZODB.POSException.ReadConflictError"), r"ReadConflictError"),
@@ -198,7 +198,7 @@
             record.msg,
             "Shouldn't load state for ZODB.tests.testConnection.StubObject"
             " 0x01 when the connection is closed")
-        self.assert_(record.exc_info)
+        self.assertTrue(record.exc_info)
 
 
 class UserMethodTests(unittest.TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/testMappingStorage.py 
new/ZODB-5.5.1/src/ZODB/tests/testMappingStorage.py
--- old/ZODB-5.4.0/src/ZODB/tests/testMappingStorage.py 2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/tests/testMappingStorage.py 2018-08-31 
19:05:22.000000000 +0200
@@ -11,6 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
+from collections import namedtuple
 import ZODB.MappingStorage
 import unittest
 import ZODB.tests.hexstorage
@@ -61,9 +62,35 @@
         self._storage = ZODB.tests.hexstorage.HexStorage(
             ZODB.MappingStorage.MappingStorage())
 
+MockTransaction = namedtuple(
+    'transaction',
+    ['user', 'description', 'extension']
+)
+
+class MappingStorageTransactionRecordTests(unittest.TestCase):
+
+    def setUp(self):
+        self._transaction_record = ZODB.MappingStorage.TransactionRecord(
+            0,
+            MockTransaction('user', 'description', 'extension'),
+            ''
+        )
+
+    def check_set__extension(self):
+        self._transaction_record._extension = 'new'
+        self.assertEqual(self._transaction_record.extension, 'new')
+
+    def check_get__extension(self):
+        self.assertEqual(
+            self._transaction_record.extension,
+            self._transaction_record._extension
+        )
+
 def test_suite():
-    suite = unittest.makeSuite(MappingStorageTests, 'check')
-    suite = unittest.makeSuite(MappingStorageHexTests, 'check')
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(MappingStorageTests, 'check'))
+    suite.addTest(unittest.makeSuite(MappingStorageHexTests, 'check'))
+    suite.addTest(unittest.makeSuite(MappingStorageTransactionRecordTests, 
'check'))
     return suite
 
 if __name__ == "__main__":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/testThreadedShutdown.py 
new/ZODB-5.5.1/src/ZODB/tests/testThreadedShutdown.py
--- old/ZODB-5.4.0/src/ZODB/tests/testThreadedShutdown.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/ZODB-5.5.1/src/ZODB/tests/testThreadedShutdown.py       2018-10-25 
17:30:38.000000000 +0200
@@ -0,0 +1,55 @@
+import threading
+import time
+import unittest
+
+import ZODB
+
+
+class ZODBClientThread(threading.Thread):
+
+    def __init__(self, db, test):
+        threading.Thread.__init__(self)
+        self._exc_info = None
+        self.setDaemon(True)
+        self.db = db
+        self.test = test
+        self.event = threading.Event()
+
+    def run(self):
+        conn = self.db.open()
+        conn.sync()
+        self.event.set()
+        time.sleep(15)
+
+        # conn.close calls self.transaction_manager.unregisterSynch(self)
+        # and this succeeds.
+        conn.close()
+
+
+class ShutdownTest(ZODB.tests.util.TestCase):
+
+    def setUp(self):
+        # Our default transaction manager is
+        # transaction._manager.ThreadTransactionManager
+        # so no need to set it.
+        ZODB.tests.util.TestCase.setUp(self)
+        self._storage = ZODB.FileStorage.FileStorage(
+            'ZODBTests.fs', create=1)
+        self._db = ZODB.DB(self._storage)
+
+    def check_shutdown(self):
+        client_thread = ZODBClientThread(self._db, self)
+        client_thread.start()
+        client_thread.event.wait()
+        # calls conn._release_resources, that calls conn.close(),
+        # that calls conn.transaction_manager.unregisterSynch(self),
+        # but from a different thread, so transaction_manager._synchs
+        # have different contents.
+        self._db.close()
+
+    def tearDown(self):
+        ZODB.tests.util.TestCase.tearDown(self)
+
+
+def test_suite():
+    return unittest.makeSuite(ShutdownTest, "check")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/testUtils.py 
new/ZODB-5.5.1/src/ZODB/tests/testUtils.py
--- old/ZODB-5.4.0/src/ZODB/tests/testUtils.py  2018-03-26 15:29:02.000000000 
+0200
+++ new/ZODB-5.5.1/src/ZODB/tests/testUtils.py  2018-08-31 19:05:22.000000000 
+0200
@@ -128,12 +128,34 @@
             self.assertEqual(get_pickle_metadata(pickle),
                             (__name__, ExampleClass.__name__))
 
+    def test_p64_bad_object(self):
+        with self.assertRaises(ValueError) as exc:
+            p64(2 ** 65)
+
+        e = exc.exception
+        # The args will be whatever the struct.error args were,
+        # which vary from version to version and across implementations,
+        # followed by the bad value
+        self.assertEqual(e.args[-1], 2 ** 65)
+
+    def test_u64_bad_object(self):
+        with self.assertRaises(ValueError) as exc:
+            u64(b'123456789')
+
+        e = exc.exception
+        # The args will be whatever the struct.error args were,
+        # which vary from version to version and across implementations,
+        # followed by the bad value
+        self.assertEqual(e.args[-1], b'123456789')
+
+
 
 class ExampleClass(object):
     pass
 
 def test_suite():
-    return unittest.TestSuite((
-        unittest.makeSuite(TestUtils),
-        doctest.DocFileSuite('../utils.txt', checker=checker),
-    ))
+    suite = unittest.defaultTestLoader.loadTestsFromName(__name__)
+    suite.addTest(
+        doctest.DocFileSuite('../utils.txt', checker=checker)
+    )
+    return suite
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ZODB-5.4.0/src/ZODB/tests/test_TransactionMetaData.py 
new/ZODB-5.5.1/src/ZODB/tests/test_TransactionMetaData.py
--- old/ZODB-5.4.0/src/ZODB/tests/test_TransactionMetaData.py   2018-03-26 
15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/tests/test_TransactionMetaData.py   2018-08-31 
19:05:22.000000000 +0200
@@ -38,32 +38,38 @@
         self.assertEqual(t.user, b'user')
         self.assertEqual(t.description, b'description')
         self.assertEqual(t.extension, dict(foo='FOO'))
-        self.assertEqual(t._extension, t.extension)
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore")
+            self.assertEqual(t._extension, t.extension)
 
     def test_constructor_default_args(self):
         t = TransactionMetaData()
         self.assertEqual(t.user, b'')
         self.assertEqual(t.description, b'')
         self.assertEqual(t.extension, {})
-        self.assertEqual(t._extension, t.extension)
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore")
+            self.assertEqual(t._extension, t.extension)
 
     def test_set_extension(self):
         t = TransactionMetaData(u'', u'', b'')
         self.assertEqual(t.user, b'')
         self.assertEqual(t.description, b'')
         self.assertEqual(t.extension, {})
-        self.assertEqual(t._extension, t.extension)
-
-        for name in 'extension', '_extension':
-            data = {name: name + 'foo'}
-            setattr(t, name, data)
-            self.assertEqual(t.extension, data)
-            self.assertEqual(t._extension, t.extension)
-            data = {}
-            setattr(t, name, data)
-            self.assertEqual(t.extension, data)
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore")
             self.assertEqual(t._extension, t.extension)
 
+            for name in 'extension', '_extension':
+                data = {name: name + 'foo'}
+                setattr(t, name, data)
+                self.assertEqual(t.extension, data)
+                self.assertEqual(t._extension, t.extension)
+                data = {}
+                setattr(t, name, data)
+                self.assertEqual(t.extension, data)
+                self.assertEqual(t._extension, t.extension)
+
     def test_used_by_connection(self):
         import ZODB
         from ZODB.MappingStorage import MappingStorage
@@ -109,4 +115,3 @@
 
 if __name__ == '__main__':
     unittest.main(defaultTest='test_suite')
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/testblob.py 
new/ZODB-5.5.1/src/ZODB/tests/testblob.py
--- old/ZODB-5.4.0/src/ZODB/tests/testblob.py   2018-03-26 15:29:02.000000000 
+0200
+++ new/ZODB-5.5.1/src/ZODB/tests/testblob.py   2018-10-13 19:13:58.000000000 
+0200
@@ -18,11 +18,7 @@
 from ZODB.tests.testConfig import ConfigTestBase
 from ZODB._compat import Pickler, Unpickler, _protocol
 
-import os
-if os.environ.get('USE_ZOPE_TESTING_DOCTEST'):
-    from zope.testing import doctest
-else:
-    import doctest
+import doctest
 
 import os
 import random
@@ -40,12 +36,7 @@
 import ZODB.tests.util
 import zope.testing.renormalizing
 
-
-try:
-    from StringIO import StringIO as BytesIO
-except ImportError:
-    # Py3
-    from io import BytesIO
+from io import BytesIO
 
 try:
     file_type = file
@@ -67,7 +58,11 @@
     now = new_time = time.time()
     while new_time <= now:
         new_time = time.time()
-    time.sleep(1)
+    if time.time() - new_time < 1.0:
+        # Detect if we're in a time monotonically increasing
+        # layer (two back-to-back calls of time.time() advance the clock
+        # by a whole second); if so, we don't need to sleep
+        time.sleep(1.0)
     return new_time
 
 
@@ -703,6 +698,14 @@
     ZODB.tests.util.setUp(test)
     test.globs['rmtree'] = zope.testing.setupstack.rmtree
 
+def timeIncreasesSetUp(test):
+    setUp(test)
+    l = test.globs['time_layer'] = 
ZODB.tests.util.MonotonicallyIncreasingTimeMinimalTestLayer('')
+    l.testSetUp()
+
+def timeIncreasesTearDown(test):
+    test.globs['time_layer'].testTearDown()
+    util.tearDown(test)
 
 def setUpBlobAdaptedFileStorage(test):
     setUp(test)
@@ -791,7 +794,7 @@
     if test_undo:
         add_test_based_on_test_class(BlobUndoTests)
 
-    suite.layer = ZODB.tests.util.MininalTestLayer(prefix+'BlobTests')
+    suite.layer = 
ZODB.tests.util.MonotonicallyIncreasingTimeMinimalTestLayer(prefix+'BlobTests')
 
     return suite
 
@@ -804,12 +807,18 @@
         "blob_basic.txt",
         "blob_consume.txt",
         "blob_tempdir.txt",
-        "blobstorage_packing.txt",
         setUp=setUp,
         tearDown=util.tearDown,
         optionflags=doctest.ELLIPSIS,
         checker=ZODB.tests.util.checker,
         ))
+    suite.addTest(doctest.DocFileSuite(
+        "blobstorage_packing.txt",
+        setUp=timeIncreasesSetUp,
+        tearDown=timeIncreasesTearDown,
+        optionflags=doctest.ELLIPSIS,
+        checker=ZODB.tests.util.checker,
+        ))
     suite.addTest(doctest.DocFileSuite(
         "blob_layout.txt",
         optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/tests/util.py 
new/ZODB-5.5.1/src/ZODB/tests/util.py
--- old/ZODB-5.4.0/src/ZODB/tests/util.py       2018-03-26 15:29:02.000000000 
+0200
+++ new/ZODB-5.5.1/src/ZODB/tests/util.py       2018-10-13 19:13:58.000000000 
+0200
@@ -29,6 +29,19 @@
 import zope.testing.setupstack
 from zope.testing import renormalizing
 
+try:
+    from unittest import mock
+except ImportError:
+    import mock
+
+import six
+import functools
+from time import time as _real_time
+from time import gmtime as _real_gmtime
+_current_time = _real_time()
+
+
+
 checker = renormalizing.RENormalizing([
     (re.compile("<(.*?) object at 0x[0-9a-f]*?>"),
      r"<\1 object at 0x000000000000>"),
@@ -37,6 +50,11 @@
      r"\1"),
     (re.compile('b(".*?")'),
      r"\1"),
+    # Persistent 4.4 changes the repr of persistent subclasses,
+    # and it is slightly different with the C extension and
+    # pure-Python module
+    (re.compile('ZODB.tests.testcrossdatabasereferences.'),
+     ''),
     # Python 3 adds module name to exceptions.
     (re.compile("ZODB.interfaces.BlobError"),
      r"BlobError"),
@@ -201,3 +219,122 @@
     for this.
     """
     transaction.manager.clearSynchs()
+
+
+class _TimeWrapper(object):
+
+    def __init__(self, granularity=1.0):
+        self._granularity = granularity
+        self._lock = ZODB.utils.Lock()
+        self.fake_gmtime = mock.Mock()
+        self.fake_time = mock.Mock()
+        self._configure_fakes()
+
+    def _configure_fakes(self):
+        def incr():
+            global _current_time # pylint:disable=global-statement
+            with self._lock:
+                _current_time = max(_real_time(), _current_time + 
self._granularity)
+            return _current_time
+        self.fake_time.side_effect = incr
+
+        def incr_gmtime(seconds=None):
+            if seconds is not None:
+                now = seconds
+            else:
+                now = incr()
+            return _real_gmtime(now)
+        self.fake_gmtime.side_effect = incr_gmtime
+
+    def install_fakes(self):
+        time.time = self.fake_time
+        time.gmtime = self.fake_gmtime
+
+    __enter__ = install_fakes
+
+    def close(self, *args):
+        time.time = _real_time
+        time.gmtime = _real_gmtime
+
+    __exit__ = close
+
+    def __call__(self, func):
+        @functools.wraps(func)
+        def wrapper(*args, **kwargs):
+            with self:
+                return func(*args, **kwargs)
+        return wrapper
+
+
+def time_monotonically_increases(func_or_granularity):
+    """
+    Decorate a unittest method with this function to cause the value
+    of :func:`time.time` and :func:`time.gmtime` to monotonically
+    increase by one each time it is called. This ensures things like
+    last modified dates always increase.
+
+    We make three guarantees about the value of :func:`time.time`
+    returned while the decorated function is running:
+
+        1. It is always *at least* the value of the *real*
+           :func:`time.time`;
+
+        2. Each call returns a value greater than the previous call;
+
+        3. Those two constraints hold across different invocations of
+           functions decorated. This decorator can be applied to a
+           method in a test case::
+
+               class TestThing(unittest.TestCase)
+                   @time_monotonically_increases
+                   def test_method(self):
+                     t = time.time()
+                      ...
+
+    It can also be applied to a bare function taking any number of
+    arguments::
+
+        @time_monotonically_increases
+        def utility_function(a, b, c=1):
+           t = time.time()
+           ...
+
+    By default, the time will be incremented in 1.0 second intervals.
+    You can specify a particular granularity as an argument; this is
+    useful to keep from running too far ahead of the real clock::
+
+        @time_monotonically_increases(0.1)
+        def smaller_increment():
+            t1 = time.time()
+            t2 = time.time()
+            assrt t2 == t1 + 0.1
+    """
+    if isinstance(func_or_granularity, (six.integer_types, float)):
+        # We're being used as a factory.
+        wrapper_factory = _TimeWrapper(func_or_granularity)
+        return wrapper_factory
+
+    # We're being used bare
+    wrapper_factory = _TimeWrapper()
+    return wrapper_factory(func_or_granularity)
+
+
+def reset_monotonic_time(value=0.0):
+    """
+    Make the monotonic clock return the real time on its next
+    call.
+    """
+
+    global _current_time # pylint:disable=global-statement
+    _current_time = value
+
+
+class MonotonicallyIncreasingTimeMinimalTestLayer(MininalTestLayer):
+
+    def testSetUp(self):
+        self.time_manager = _TimeWrapper()
+        self.time_manager.install_fakes()
+
+    def testTearDown(self):
+        self.time_manager.close()
+        reset_monotonic_time()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB/utils.py 
new/ZODB-5.5.1/src/ZODB/utils.py
--- old/ZODB-5.4.0/src/ZODB/utils.py    2018-03-26 15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB/utils.py    2018-08-31 19:05:22.000000000 +0200
@@ -18,10 +18,10 @@
 import time
 import threading
 from binascii import hexlify, unhexlify
-from struct import pack, unpack
+
 from tempfile import mkstemp
 
-from persistent.TimeStamp import TimeStamp
+from persistent.timestamp import TimeStamp
 
 from ZODB._compat import Unpickler
 from ZODB._compat import BytesIO
@@ -84,13 +84,24 @@
 # The distinction between ints and longs is blurred in Python 2.2,
 # so u64() are U64() really the same.
 
+_OID_STRUCT = struct.Struct('>Q')
+_OID_PACK = _OID_STRUCT.pack
+_OID_UNPACK = _OID_STRUCT.unpack
+
+
 def p64(v):
-    """Pack an integer or long into a 8-byte string"""
-    return pack(">Q", v)
+    """Pack an integer or long into a 8-byte string."""
+    try:
+        return _OID_PACK(v)
+    except struct.error as e:
+        raise ValueError(*(e.args + (v,)))
 
 def u64(v):
     """Unpack an 8-byte string into a 64-bit long integer."""
-    return unpack(">Q", v)[0]
+    try:
+        return _OID_UNPACK(v)[0]
+    except struct.error as e:
+        raise ValueError(*(e.args + (v,)))
 
 U64 = u64
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB.egg-info/PKG-INFO 
new/ZODB-5.5.1/src/ZODB.egg-info/PKG-INFO
--- old/ZODB-5.4.0/src/ZODB.egg-info/PKG-INFO   2018-03-26 15:29:03.000000000 
+0200
+++ new/ZODB-5.5.1/src/ZODB.egg-info/PKG-INFO   2018-10-25 17:52:53.000000000 
+0200
@@ -1,10 +1,12 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
 Name: ZODB
-Version: 5.4.0
+Version: 5.5.1
 Summary: ZODB, a Python object-oriented database
 Home-page: http://www.zodb.org/
-Author: Zope Foundation and Contributors
-Author-email: [email protected]
+Author: Jim Fulton
+Author-email: [email protected]
+Maintainer: Zope Foundation and Contributors
+Maintainer-email: [email protected]
 License: ZPL 2.1
 Description: =======================================
         ZODB, a Python object-oriented database
@@ -60,6 +62,35 @@
          Change History
         ================
         
+        5.5.1 (2018-10-25)
+        ==================
+        
+        - Fix KeyError on releasing resources of a Connection when closing the 
DB.
+          This requires at least version 2.4 of the `transaction` package.
+          See `issue 208 <https://github.com/zopefoundation/ZODB/issues/208>`.
+        
+        5.5.0 (2018-10-13)
+        ==================
+        
+        - Add support for Python 3.7.
+        
+        - Bump the dependency on zodbpickle to at least 1.0.1. This is
+          required to avoid a memory leak on Python 2.7. See `issue 203
+          <https://github.com/zopefoundation/ZODB/issues/203>`_.
+        
+        - Bump the dependency on persistent to at least 4.4.0.
+        
+        - Make the internal support functions for dealing with OIDs (``p64``
+          and ``u64``) somewhat faster and raise more informative
+          exceptions on certain types of bad input. See `issue 216
+          <https://github.com/zopefoundation/ZODB/issues/216>`_.
+        
+        - Remove support for ``python setup.py test``. It hadn't been working
+          for some time. See `issue #218
+          <https://github.com/zopefoundation/ZODB/issues/218>`_.
+        
+        - Make the tests run faster by avoiding calls to ``time.sleep()``.
+        
         5.4.0 (2018-03-26)
         ==================
         
@@ -100,10 +131,10 @@
           cost of being very slightly less efficient for old-style classes.
         
           .. note:: On Python 2, this will now allow open ``file`` objects
-                               (but **not** open blobs or sockets) to be 
pickled (loading
-                               the object will result in a closed file); 
previously this
-                               would result in a ``TypeError``. Doing so is not
-                               recommended as they cannot be loaded in Python 
3.
+                    (but **not** open blobs or sockets) to be pickled (loading
+                    the object will result in a closed file); previously this
+                    would result in a ``TypeError``. Doing so is not
+                    recommended as they cannot be loaded in Python 3.
         
           See `issue 179 <https://github.com/zopefoundation/ZODB/pull/179>`_.
         
@@ -203,7 +234,7 @@
         Major internal improvements and cleanups plus:
         
         - Added a connection ``prefetch`` method that can be used to request
-          that a storage prefect data an application will need::
+          that a storage prefetch data an application will need::
         
             conn.prefetch(obj, ...)
         
@@ -540,6 +571,7 @@
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Database
@@ -548,3 +580,4 @@
 Classifier: Operating System :: Unix
 Classifier: Framework :: ZODB
 Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
+Provides-Extra: test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB.egg-info/SOURCES.txt 
new/ZODB-5.5.1/src/ZODB.egg-info/SOURCES.txt
--- old/ZODB-5.4.0/src/ZODB.egg-info/SOURCES.txt        2018-03-26 
15:29:03.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB.egg-info/SOURCES.txt        2018-10-25 
17:52:53.000000000 +0200
@@ -183,6 +183,7 @@
 src/ZODB/tests/testPersistentWeakref.py
 src/ZODB/tests/testRecover.py
 src/ZODB/tests/testSerialize.py
+src/ZODB/tests/testThreadedShutdown.py
 src/ZODB/tests/testUtils.py
 src/ZODB/tests/testZODB.py
 src/ZODB/tests/test_TransactionMetaData.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/src/ZODB.egg-info/requires.txt 
new/ZODB-5.5.1/src/ZODB.egg-info/requires.txt
--- old/ZODB-5.4.0/src/ZODB.egg-info/requires.txt       2018-03-26 
15:29:03.000000000 +0200
+++ new/ZODB-5.5.1/src/ZODB.egg-info/requires.txt       2018-10-25 
17:52:53.000000000 +0200
@@ -1,13 +1,16 @@
-persistent >= 4.2.0
-BTrees >= 4.2.0
+persistent>=4.4.0
+BTrees>=4.2.0
 ZConfig
-transaction >= 2.0.3
+transaction>=2.4
 six
 zc.lockfile
 zope.interface
-zodbpickle >= 0.6.0
+zodbpickle>=1.0.1
 
 [test]
 manuel
 zope.testing
-zope.testrunner >= 4.4.6
+zope.testrunner>=4.4.6
+
+[test:python_version == "2.7"]
+mock
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ZODB-5.4.0/tox.ini new/ZODB-5.5.1/tox.ini
--- old/ZODB-5.4.0/tox.ini      2018-03-26 15:29:02.000000000 +0200
+++ new/ZODB-5.5.1/tox.ini      2018-10-13 19:13:58.000000000 +0200
@@ -2,7 +2,7 @@
 # Jython 2.7rc2 does work, but unfortunately has an issue running
 # with Tox 1.9.2 (http://bugs.jython.org/issue2325)
 #envlist = py26,py27,py33,py34,pypy,simple,jython,pypy3
-envlist = py27,py34,py35,py36,pypy,simple,pypy3
+envlist = py27,py34,py35,py36,py37,pypy,pypy3
 
 [testenv]
 # ZODB.tests.testdocumentation needs to find
@@ -13,22 +13,10 @@
 # out of the tox site-packages.
 usedevelop = true
 commands =
-# Run unit tests first.
-    zope-testrunner -u --test-path=src []
-# Only run functional tests if unit tests pass.
-    zope-testrunner -f --test-path=src []
+    zope-testrunner --test-path=src []
 deps =
     .[test]
 
-
-[testenv:simple]
-# Test that 'setup.py test' works
-basepython =
-    python2.7
-commands =
-    python setup.py test -q
-deps = {[testenv]deps}
-
 [testenv:coverage]
 basepython = python2.7
 commands =


Reply via email to