pybsddb 4.8.4 integration. Please, comment in issue #8156
diff --git a/Lib/bsddb/__init__.py b/Lib/bsddb/__init__.py
index 07c7c9d..dfa8a66 100644
--- a/Lib/bsddb/__init__.py
+++ b/Lib/bsddb/__init__.py
@@ -33,7 +33,7 @@
 #----------------------------------------------------------------------
 
 
-"""Support for Berkeley DB 4.0 through 4.7 with a simple interface.
+"""Support for Berkeley DB 4.1 through 4.8 with a simple interface.
 
 For the full featured object oriented interface use the bsddb.db module
 instead.  It mirrors the Oracle Berkeley DB C API.
@@ -42,11 +42,12 @@
 import sys
 absolute_import = (sys.version_info[0] >= 3)
 
-if sys.py3kwarning:
-    import warnings
-    warnings.warnpy3k("in 3.x, the bsddb module has been removed; "
-                      "please use the pybsddb project instead",
-                      DeprecationWarning, 2)
+if (sys.version_info >= (2, 6)) and (sys.version_info < (3, 0)) :
+    if sys.py3kwarning and (__name__ != 'bsddb3') :
+        import warnings
+        warnings.warnpy3k("in 3.x, the bsddb module has been removed; "
+                          "please use the pybsddb project instead",
+                          DeprecationWarning, 2)
 
 try:
     if __name__ == 'bsddb3':
@@ -81,7 +82,7 @@
 
 from weakref import ref
 
-if sys.version_info[0:2] <= (2, 5) :
+if sys.version_info < (2, 6) :
     import UserDict
     MutableMapping = UserDict.DictMixin
 else :
@@ -256,7 +257,7 @@
         self._checkOpen()
         return _DeadlockWrap(lambda: len(self.db))  # len(self.db)
 
-    if sys.version_info[0:2] >= (2, 6) :
+    if sys.version_info >= (2, 6) :
         def __repr__(self) :
             if self.isOpen() :
                 return repr(dict(_DeadlockWrap(self.db.items)))
@@ -442,8 +443,10 @@
 # Berkeley DB was too.
 
 try:
-    import thread
-    del thread
+    # 2to3 automatically changes "import thread" to "import _thread"
+    import thread as T
+    del T
+
 except ImportError:
     db.DB_THREAD = 0
 
diff --git a/Lib/bsddb/dbobj.py b/Lib/bsddb/dbobj.py
index 1e42397..c7c7322 100644
--- a/Lib/bsddb/dbobj.py
+++ b/Lib/bsddb/dbobj.py
@@ -29,7 +29,7 @@
 else :
     import db
 
-if sys.version_info[0:2] <= (2, 5) :
+if sys.version_info < (2, 6) :
     try:
         from UserDict import DictMixin
     except ImportError:
@@ -110,15 +110,17 @@
     def log_stat(self, *args, **kwargs):
         return self._cobj.log_stat(*args, **kwargs)
 
-    if db.version() >= (4,1):
-        def dbremove(self, *args, **kwargs):
-            return self._cobj.dbremove(*args, **kwargs)
-        def dbrename(self, *args, **kwargs):
-            return self._cobj.dbrename(*args, **kwargs)
-        def set_encrypt(self, *args, **kwargs):
-            return self._cobj.set_encrypt(*args, **kwargs)
+    def dbremove(self, *args, **kwargs):
+        return self._cobj.dbremove(*args, **kwargs)
+    def dbrename(self, *args, **kwargs):
+        return self._cobj.dbrename(*args, **kwargs)
+    def set_encrypt(self, *args, **kwargs):
+        return self._cobj.set_encrypt(*args, **kwargs)
 
     if db.version() >= (4,4):
+        def fileid_reset(self, *args, **kwargs):
+            return self._cobj.fileid_reset(*args, **kwargs)
+
         def lsn_reset(self, *args, **kwargs):
             return self._cobj.lsn_reset(*args, **kwargs)
 
@@ -138,7 +140,7 @@
     def __delitem__(self, arg):
         del self._cobj[arg]
 
-    if sys.version_info[0:2] >= (2, 6) :
+    if sys.version_info >= (2, 6) :
         def __iter__(self) :
             return self._cobj.__iter__()
 
@@ -229,9 +231,8 @@
     def set_get_returns_none(self, *args, **kwargs):
         return self._cobj.set_get_returns_none(*args, **kwargs)
 
-    if db.version() >= (4,1):
-        def set_encrypt(self, *args, **kwargs):
-            return self._cobj.set_encrypt(*args, **kwargs)
+    def set_encrypt(self, *args, **kwargs):
+        return self._cobj.set_encrypt(*args, **kwargs)
 
 
 class DBSequence:
diff --git a/Lib/bsddb/dbshelve.py b/Lib/bsddb/dbshelve.py
index 891c7f2..e3f6d4c 100644
--- a/Lib/bsddb/dbshelve.py
+++ b/Lib/bsddb/dbshelve.py
@@ -29,9 +29,6 @@
 
 #------------------------------------------------------------------------
 
-import cPickle
-import sys
-
 import sys
 absolute_import = (sys.version_info[0] >= 3)
 if absolute_import :
@@ -40,13 +37,41 @@
 else :
     import db
 
+if sys.version_info[0] >= 3 :
+    import cPickle  # Will be converted to "pickle" by "2to3"
+else :
+    if sys.version_info < (2, 6) :
+        import cPickle
+    else :
+        # When we drop support for python 2.3 and 2.4
+        # we could use: (in 2.5 we need a __future__ statement)
+        #
+        #    with warnings.catch_warnings():
+        #        warnings.filterwarnings(...)
+        #        ...
+        #
+        # We can not use "with" as is, because it would be invalid syntax
+        # in python 2.3, 2.4 and (with no __future__) 2.5.
+        # Here we simulate "with" following PEP 343 :
+        import warnings
+        w = warnings.catch_warnings()
+        w.__enter__()
+        try :
+            warnings.filterwarnings('ignore',
+                message='the cPickle module has been removed in Python 3.0',
+                category=DeprecationWarning)
+            import cPickle
+        finally :
+            w.__exit__()
+        del w
+
 #At version 2.3 cPickle switched to using protocol instead of bin
-if sys.version_info[:3] >= (2, 3, 0):
+if sys.version_info >= (2, 3):
     HIGHEST_PROTOCOL = cPickle.HIGHEST_PROTOCOL
 # In python 2.3.*, "cPickle.dumps" accepts no
 # named parameters. "pickle.dumps" accepts them,
 # so this seems a bug.
-    if sys.version_info[:3] < (2, 4, 0):
+    if sys.version_info < (2, 4):
         def _dumps(object, protocol):
             return cPickle.dumps(object, protocol)
     else :
@@ -59,11 +84,16 @@
         return cPickle.dumps(object, bin=protocol)
 
 
-try:
-    from UserDict import DictMixin
-except ImportError:
-    # DictMixin is new in Python 2.3
-    class DictMixin: pass
+if sys.version_info < (2, 6) :
+    try:
+        from UserDict import DictMixin
+    except ImportError:
+        # DictMixin is new in Python 2.3
+        class DictMixin: pass
+    MutableMapping = DictMixin
+else :
+    import collections
+    MutableMapping = collections.MutableMapping
 
 #------------------------------------------------------------------------
 
@@ -106,7 +136,7 @@
 class DBShelveError(db.DBError): pass
 
 
-class DBShelf(DictMixin):
+class DBShelf(MutableMapping):
     """A shelf to hold pickled objects, built upon a bsddb DB object.  It
     automatically pickles/unpickles data objects going to/from the DB.
     """
@@ -157,6 +187,17 @@
         else:
             return self.db.keys()
 
+    if sys.version_info >= (2, 6) :
+        def __iter__(self) :  # XXX: Load all keys in memory :-(
+            for k in self.db.keys() :
+                yield k
+
+        # Do this when "DB"  support iteration
+        # Or is it enough to pass thru "getattr"?
+        #
+        # def __iter__(self) :
+        #    return self.db.__iter__()
+
 
     def open(self, *args, **kwargs):
         self.db.open(*args, **kwargs)
diff --git a/Lib/bsddb/dbtables.py b/Lib/bsddb/dbtables.py
index 02ddcdc..3ebc68d 100644
--- a/Lib/bsddb/dbtables.py
+++ b/Lib/bsddb/dbtables.py
@@ -22,7 +22,35 @@
 import copy
 import random
 import struct
-import cPickle as pickle
+
+
+if sys.version_info[0] >= 3 :
+    import pickle
+else :
+    if sys.version_info < (2, 6) :
+        import cPickle as pickle
+    else :
+        # When we drop support for python 2.3 and 2.4
+        # we could use: (in 2.5 we need a __future__ statement)
+        #
+        #    with warnings.catch_warnings():
+        #        warnings.filterwarnings(...)
+        #        ...
+        #
+        # We can not use "with" as is, because it would be invalid syntax
+        # in python 2.3, 2.4 and (with no __future__) 2.5.
+        # Here we simulate "with" following PEP 343 :
+        import warnings
+        w = warnings.catch_warnings()
+        w.__enter__()
+        try :
+            warnings.filterwarnings('ignore',
+                message='the cPickle module has been removed in Python 3.0',
+                category=DeprecationWarning)
+            import cPickle as pickle
+        finally :
+            w.__exit__()
+        del w
 
 try:
     # For Pythons w/distutils pybsddb
@@ -31,12 +59,6 @@
     # For Python 2.3
     from bsddb import db
 
-# XXX(nnorwitz): is this correct? DBIncompleteError is conditional in _bsddb.c
-if not hasattr(db,"DBIncompleteError") :
-    class DBIncompleteError(Exception):
-        pass
-    db.DBIncompleteError = DBIncompleteError
-
 class TableDBError(StandardError):
     pass
 class TableAlreadyExists(TableDBError):
@@ -261,16 +283,10 @@
             self.env = None
 
     def checkpoint(self, mins=0):
-        try:
-            self.env.txn_checkpoint(mins)
-        except db.DBIncompleteError:
-            pass
+        self.env.txn_checkpoint(mins)
 
     def sync(self):
-        try:
-            self.db.sync()
-        except db.DBIncompleteError:
-            pass
+        self.db.sync()
 
     def _db_print(self) :
         """Print the database to stdout for debugging"""
@@ -659,6 +675,13 @@
             a = atuple[1]
             b = btuple[1]
             if type(a) is type(b):
+
+                # Needed for python 3. "cmp" vanished in 3.0.1
+                def cmp(a, b) :
+                    if a==b : return 0
+                    if a<b : return -1
+                    return 1
+
                 if isinstance(a, PrefixCond) and isinstance(b, PrefixCond):
                     # longest prefix first
                     return cmp(len(b.prefix), len(a.prefix))
diff --git a/Lib/bsddb/test/test_all.py b/Lib/bsddb/test/test_all.py
index 39231c6..e9fe618 100644
--- a/Lib/bsddb/test/test_all.py
+++ b/Lib/bsddb/test/test_all.py
@@ -15,6 +15,51 @@
 if sys.version_info[0] >= 3 :
     charset = "iso8859-1"  # Full 8 bit
 
+    class logcursor_py3k(object) :
+        def __init__(self, env) :
+            self._logcursor = env.log_cursor()
+
+        def __getattr__(self, v) :
+            return getattr(self._logcursor, v)
+
+        def __next__(self) :
+            v = getattr(self._logcursor, "next")()
+            if v is not None :
+                v = (v[0], v[1].decode(charset))
+            return v
+
+        next = __next__
+
+        def first(self) :
+            v = self._logcursor.first()
+            if v is not None :
+                v = (v[0], v[1].decode(charset))
+            return v
+
+        def last(self) :
+            v = self._logcursor.last()
+            if v is not None :
+                v = (v[0], v[1].decode(charset))
+            return v
+
+        def prev(self) :
+            v = self._logcursor.prev()
+            if v is not None :
+                v = (v[0], v[1].decode(charset))
+            return v
+
+        def current(self) :
+            v = self._logcursor.current()
+            if v is not None :
+                v = (v[0], v[1].decode(charset))
+            return v
+
+        def set(self, lsn) :
+            v = self._logcursor.set(lsn)
+            if v is not None :
+                v = (v[0], v[1].decode(charset))
+            return v
+
     class cursor_py3k(object) :
         def __init__(self, db, *args, **kwargs) :
             self._dbcursor = db.cursor(*args, **kwargs)
@@ -71,12 +116,12 @@
             v = self._dbcursor.next_nodup()
             return self._fix(v)
 
-        def put(self, key, value, flags=0, dlen=-1, doff=-1) :
+        def put(self, key, data, flags=0, dlen=-1, doff=-1) :
             if isinstance(key, str) :
                 key = bytes(key, charset)
-            if isinstance(value, str) :
-                value = bytes(value, charset)
-            return self._dbcursor.put(key, value, flags=flags, dlen=dlen,
+            if isinstance(data, str) :
+                value = bytes(data, charset)
+            return self._dbcursor.put(key, data, flags=flags, dlen=dlen,
                     doff=doff)
 
         def current(self, flags=0, dlen=-1, doff=-1) :
@@ -203,12 +248,26 @@
                 k = bytes(k, charset)
             return self._db.has_key(k, txn=txn)
 
-        def put(self, key, value, txn=None, flags=0, dlen=-1, doff=-1) :
+        def set_re_delim(self, c) :
+            if isinstance(c, str) :  # We can use a numeric value byte too
+                c = bytes(c, charset)
+            return self._db.set_re_delim(c)
+
+        def set_re_pad(self, c) :
+            if isinstance(c, str) :  # We can use a numeric value byte too
+                c = bytes(c, charset)
+            return self._db.set_re_pad(c)
+
+        def get_re_source(self) :
+            source = self._db.get_re_source()
+            return source.decode(charset)
+
+        def put(self, key, data, txn=None, flags=0, dlen=-1, doff=-1) :
             if isinstance(key, str) :
                 key = bytes(key, charset)
-            if isinstance(value, str) :
-                value = bytes(value, charset)
-            return self._db.put(key, value, flags=flags, txn=txn, dlen=dlen,
+            if isinstance(data, str) :
+                value = bytes(data, charset)
+            return self._db.put(key, data, flags=flags, txn=txn, dlen=dlen,
                     doff=doff)
 
         def append(self, value, txn=None) :
@@ -221,6 +280,11 @@
                 key = bytes(key, charset)
             return self._db.get_size(key)
 
+        def exists(self, key, *args, **kwargs) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            return self._db.exists(key, *args, **kwargs)
+
         def get(self, key, default="MagicCookie", txn=None, flags=0, dlen=-1, doff=-1) :
             if isinstance(key, str) :
                 key = bytes(key, charset)
@@ -288,13 +352,21 @@
                         key = key.decode(charset)
                     data = data.decode(charset)
                     key = self._callback(key, data)
-                    if (key != bsddb._db.DB_DONOTINDEX) and isinstance(key,
-                            str) :
-                        key = bytes(key, charset)
+                    if (key != bsddb._db.DB_DONOTINDEX) :
+                        if isinstance(key, str) :
+                            key = bytes(key, charset)
+                        elif isinstance(key, list) :
+                            key2 = []
+                            for i in key :
+                                if isinstance(i, str) :
+                                    i = bytes(i, charset)
+                                key2.append(i)
+                            key = key2
                     return key
 
             return self._db.associate(secondarydb._db,
-                    associate_callback(callback).callback, flags=flags, txn=txn)
+                    associate_callback(callback).callback, flags=flags,
+                    txn=txn)
 
         def cursor(self, txn=None, flags=0) :
             return cursor_py3k(self._db, txn=txn, flags=flags)
@@ -310,6 +382,21 @@
         def __getattr__(self, v) :
             return getattr(self._dbenv, v)
 
+        def log_cursor(self, flags=0) :
+            return logcursor_py3k(self._dbenv)
+
+        def get_lg_dir(self) :
+            return self._dbenv.get_lg_dir().decode(charset)
+
+        def get_tmp_dir(self) :
+            return self._dbenv.get_tmp_dir().decode(charset)
+
+        def get_data_dirs(self) :
+            # Have to use a list comprehension and not
+            # generators, because we are supporting Python 2.3.
+            return tuple(
+                [i.decode(charset) for i in self._dbenv.get_data_dirs()])
+
     class DBSequence_py3k(object) :
         def __init__(self, db, *args, **kwargs) :
             self._db=db
@@ -332,7 +419,10 @@
 
     bsddb._db.DBEnv_orig = bsddb._db.DBEnv
     bsddb._db.DB_orig = bsddb._db.DB
-    bsddb._db.DBSequence_orig = bsddb._db.DBSequence
+    if bsddb.db.version() <= (4, 3) :
+        bsddb._db.DBSequence_orig = None
+    else :
+        bsddb._db.DBSequence_orig = bsddb._db.DBSequence
 
     def do_proxy_db_py3k(flag) :
         flag2 = do_proxy_db_py3k.flag
@@ -396,8 +486,12 @@
     print 'bsddb.db.version():   %s' % (db.version(), )
     print 'bsddb.db.__version__: %s' % db.__version__
     print 'bsddb.db.cvsid:       %s' % db.cvsid
-    print 'py module:            %s' % bsddb.__file__
-    print 'extension module:     %s' % bsddb._bsddb.__file__
+
+    # Workaround for allowing generating an EGGs as a ZIP files.
+    suffix="__"
+    print 'py module:            %s' % getattr(bsddb, "__file"+suffix)
+    print 'extension module:     %s' % getattr(bsddb, "__file"+suffix)
+
     print 'python version:       %s' % sys.version
     print 'My pid:               %s' % os.getpid()
     print '-=' * 38
@@ -481,6 +575,8 @@
     test_modules = [
         'test_associate',
         'test_basics',
+        'test_dbenv',
+        'test_db',
         'test_compare',
         'test_compat',
         'test_cursor_pget_bug',
@@ -489,6 +585,7 @@
         'test_dbtables',
         'test_distributed_transactions',
         'test_early_close',
+        'test_fileid',
         'test_get_none',
         'test_join',
         'test_lock',
diff --git a/Lib/bsddb/test/test_associate.py b/Lib/bsddb/test/test_associate.py
index c0da3e8..6f240a0 100644
--- a/Lib/bsddb/test/test_associate.py
+++ b/Lib/bsddb/test/test_associate.py
@@ -148,12 +148,8 @@
         self.secDB = None
         self.primary = db.DB(self.env)
         self.primary.set_get_returns_none(2)
-        if db.version() >= (4, 1):
-            self.primary.open(self.filename, "primary", self.dbtype,
-                          db.DB_CREATE | db.DB_THREAD | self.dbFlags, txn=txn)
-        else:
-            self.primary.open(self.filename, "primary", self.dbtype,
-                          db.DB_CREATE | db.DB_THREAD | self.dbFlags)
+        self.primary.open(self.filename, "primary", self.dbtype,
+                      db.DB_CREATE | db.DB_THREAD | self.dbFlags, txn=txn)
 
     def closeDB(self):
         if self.cur:
@@ -169,12 +165,7 @@
         return self.primary
 
 
-    def test01_associateWithDB(self):
-        if verbose:
-            print '\n', '-=' * 30
-            print "Running %s.test01_associateWithDB..." % \
-                  self.__class__.__name__
-
+    def _associateWithDB(self, getGenre):
         self.createDB()
 
         self.secDB = db.DB(self.env)
@@ -182,19 +173,21 @@
         self.secDB.set_get_returns_none(2)
         self.secDB.open(self.filename, "secondary", db.DB_BTREE,
                    db.DB_CREATE | db.DB_THREAD | self.dbFlags)
-        self.getDB().associate(self.secDB, self.getGenre)
+        self.getDB().associate(self.secDB, getGenre)
 
         self.addDataToDB(self.getDB())
 
         self.finish_test(self.secDB)
 
-
-    def test02_associateAfterDB(self):
+    def test01_associateWithDB(self):
         if verbose:
             print '\n', '-=' * 30
-            print "Running %s.test02_associateAfterDB..." % \
+            print "Running %s.test01_associateWithDB..." % \
                   self.__class__.__name__
 
+        return self._associateWithDB(self.getGenre)
+
+    def _associateAfterDB(self, getGenre) :
         self.createDB()
         self.addDataToDB(self.getDB())
 
@@ -204,10 +197,35 @@
                    db.DB_CREATE | db.DB_THREAD | self.dbFlags)
 
         # adding the DB_CREATE flag will cause it to index existing records
-        self.getDB().associate(self.secDB, self.getGenre, db.DB_CREATE)
+        self.getDB().associate(self.secDB, getGenre, db.DB_CREATE)
 
         self.finish_test(self.secDB)
 
+    def test02_associateAfterDB(self):
+        if verbose:
+            print '\n', '-=' * 30
+            print "Running %s.test02_associateAfterDB..." % \
+                  self.__class__.__name__
+
+        return self._associateAfterDB(self.getGenre)
+
+    if db.version() >= (4, 6):
+        def test03_associateWithDB(self):
+            if verbose:
+                print '\n', '-=' * 30
+                print "Running %s.test03_associateWithDB..." % \
+                      self.__class__.__name__
+
+            return self._associateWithDB(self.getGenreList)
+
+        def test04_associateAfterDB(self):
+            if verbose:
+                print '\n', '-=' * 30
+                print "Running %s.test04_associateAfterDB..." % \
+                      self.__class__.__name__
+
+            return self._associateAfterDB(self.getGenreList)
+
 
     def finish_test(self, secDB, txn=None):
         # 'Blues' should not be in the secondary database
@@ -277,6 +295,12 @@
         else:
             return genre
 
+    def getGenreList(self, priKey, PriData) :
+        v = self.getGenre(priKey, PriData)
+        if type(v) == type("") :
+            v = [v]
+        return v
+
 
 #----------------------------------------------------------------------
 
@@ -322,10 +346,7 @@
             self.secDB.set_get_returns_none(2)
             self.secDB.open(self.filename, "secondary", db.DB_BTREE,
                        db.DB_CREATE | db.DB_THREAD, txn=txn)
-            if db.version() >= (4,1):
-                self.getDB().associate(self.secDB, self.getGenre, txn=txn)
-            else:
-                self.getDB().associate(self.secDB, self.getGenre)
+            self.getDB().associate(self.secDB, self.getGenre, txn=txn)
 
             self.addDataToDB(self.getDB(), txn=txn)
         except:
@@ -426,8 +447,7 @@
     suite.addTest(unittest.makeSuite(AssociateBTreeTestCase))
     suite.addTest(unittest.makeSuite(AssociateRecnoTestCase))
 
-    if db.version() >= (4, 1):
-        suite.addTest(unittest.makeSuite(AssociateBTreeTxnTestCase))
+    suite.addTest(unittest.makeSuite(AssociateBTreeTxnTestCase))
 
     suite.addTest(unittest.makeSuite(ShelveAssociateHashTestCase))
     suite.addTest(unittest.makeSuite(ShelveAssociateBTreeTestCase))
diff --git a/Lib/bsddb/test/test_basics.py b/Lib/bsddb/test/test_basics.py
index b713496..8b05c61 100644
--- a/Lib/bsddb/test/test_basics.py
+++ b/Lib/bsddb/test/test_basics.py
@@ -33,6 +33,7 @@
 
 class BasicTestCase(unittest.TestCase):
     dbtype       = db.DB_UNKNOWN  # must be set in derived class
+    cachesize    = (0, 1024*1024, 1)
     dbopenflags  = 0
     dbsetflags   = 0
     dbmode       = 0660
@@ -43,6 +44,13 @@
 
     _numKeys      = 1002    # PRIVATE.  NOTE: must be an even value
 
+    import sys
+    if sys.version_info < (2, 4):
+        def assertTrue(self, expr, msg=None):
+            self.failUnless(expr,msg=msg)
+        def assertFalse(self, expr, msg=None):
+            self.failIf(expr,msg=msg)
+
     def setUp(self):
         if self.useEnv:
             self.homeDir=get_new_environment_path()
@@ -50,7 +58,8 @@
                 self.env = db.DBEnv()
                 self.env.set_lg_max(1024*1024)
                 self.env.set_tx_max(30)
-                self.env.set_tx_timestamp(int(time.time()))
+                self._t = int(time.time())
+                self.env.set_tx_timestamp(self._t)
                 self.env.set_flags(self.envsetflags, 1)
                 self.env.open(self.homeDir, self.envflags | db.DB_CREATE)
                 self.filename = "test"
@@ -64,6 +73,15 @@
 
         # create and open the DB
         self.d = db.DB(self.env)
+        if not self.useEnv :
+            if db.version() >= (4, 2) :
+                self.d.set_cachesize(*self.cachesize)
+                cachesize = self.d.get_cachesize()
+                self.assertEqual(cachesize[0], self.cachesize[0])
+                self.assertEqual(cachesize[2], self.cachesize[2])
+                # Berkeley DB expands the cache 25% accounting overhead,
+                # if the cache is small.
+                self.assertEqual(125, int(100.0*cachesize[1]/self.cachesize[1]))
         self.d.set_flags(self.dbsetflags)
         if self.dbname:
             self.d.open(self.filename, self.dbname, self.dbtype,
@@ -74,6 +92,10 @@
                         dbtype = self.dbtype,
                         flags = self.dbopenflags|db.DB_CREATE)
 
+        if not self.useEnv:
+            self.assertRaises(db.DBInvalidArgError,
+                    self.d.set_cachesize, *self.cachesize)
+
         self.populateDB()
 
 
@@ -139,7 +161,11 @@
         try:
             d.delete('abcd')
         except db.DBNotFoundError, val:
-            self.assertEqual(val.args[0], db.DB_NOTFOUND)
+            import sys
+            if sys.version_info < (2, 6) :
+                self.assertEqual(val[0], db.DB_NOTFOUND)
+            else :
+                self.assertEqual(val.args[0], db.DB_NOTFOUND)
             if verbose: print val
         else:
             self.fail("expected exception")
@@ -158,7 +184,11 @@
         try:
             d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE)
         except db.DBKeyExistError, val:
-            self.assertEqual(val.args[0], db.DB_KEYEXIST)
+            import sys
+            if sys.version_info < (2, 6) :
+                self.assertEqual(val[0], db.DB_KEYEXIST)
+            else :
+                self.assertEqual(val.args[0], db.DB_KEYEXIST)
             if verbose: print val
         else:
             self.fail("expected exception")
@@ -268,6 +298,21 @@
             pprint(values[:10])
 
 
+    #----------------------------------------
+
+    def test02b_SequenceMethods(self):
+        d = self.d
+
+        for key in ['0002', '0101', '0401', '0701', '0998']:
+            data = d[key]
+            self.assertEqual(data, self.makeData(key))
+            if verbose:
+                print data
+
+        self.assertTrue(hasattr(d, "__contains__"))
+        self.assertTrue("0401" in d)
+        self.assertFalse("1234" in d)
+
 
     #----------------------------------------
 
@@ -293,7 +338,11 @@
                 rec = c.next()
             except db.DBNotFoundError, val:
                 if get_raises_error:
-                    self.assertEqual(val.args[0], db.DB_NOTFOUND)
+                    import sys
+                    if sys.version_info < (2, 6) :
+                        self.assertEqual(val[0], db.DB_NOTFOUND)
+                    else :
+                        self.assertEqual(val.args[0], db.DB_NOTFOUND)
                     if verbose: print val
                     rec = None
                 else:
@@ -314,7 +363,11 @@
                 rec = c.prev()
             except db.DBNotFoundError, val:
                 if get_raises_error:
-                    self.assertEqual(val.args[0], db.DB_NOTFOUND)
+                    import sys
+                    if sys.version_info < (2, 6) :
+                        self.assertEqual(val[0], db.DB_NOTFOUND)
+                    else :
+                        self.assertEqual(val.args[0], db.DB_NOTFOUND)
                     if verbose: print val
                     rec = None
                 else:
@@ -337,7 +390,11 @@
         try:
             n = c.set('bad key')
         except db.DBNotFoundError, val:
-            self.assertEqual(val.args[0], db.DB_NOTFOUND)
+            import sys
+            if sys.version_info < (2, 6) :
+                self.assertEqual(val[0], db.DB_NOTFOUND)
+            else :
+                self.assertEqual(val.args[0], db.DB_NOTFOUND)
             if verbose: print val
         else:
             if set_raises_error:
@@ -351,7 +408,11 @@
         try:
             n = c.get_both('0404', 'bad data')
         except db.DBNotFoundError, val:
-            self.assertEqual(val.args[0], db.DB_NOTFOUND)
+            import sys
+            if sys.version_info < (2, 6) :
+                self.assertEqual(val[0], db.DB_NOTFOUND)
+            else :
+                self.assertEqual(val.args[0], db.DB_NOTFOUND)
             if verbose: print val
         else:
             if get_raises_error:
@@ -380,7 +441,11 @@
             rec = c.current()
         except db.DBKeyEmptyError, val:
             if get_raises_error:
-                self.assertEqual(val.args[0], db.DB_KEYEMPTY)
+                import sys
+                if sys.version_info < (2, 6) :
+                    self.assertEqual(val[0], db.DB_KEYEMPTY)
+                else :
+                    self.assertEqual(val.args[0], db.DB_KEYEMPTY)
                 if verbose: print val
             else:
                 self.fail("unexpected DBKeyEmptyError")
@@ -425,7 +490,11 @@
                 # a bug may cause a NULL pointer dereference...
                 getattr(c, method)(*args)
             except db.DBError, val:
-                self.assertEqual(val.args[0], 0)
+                import sys
+                if sys.version_info < (2, 6) :
+                    self.assertEqual(val[0], 0)
+                else :
+                    self.assertEqual(val.args[0], 0)
                 if verbose: print val
             else:
                 self.fail("no exception raised when using a buggy cursor's"
@@ -477,6 +546,15 @@
         self.assertEqual(old, 1)
         self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=0)
 
+    if db.version() >= (4, 6):
+        def test03d_SimpleCursorPriority(self) :
+            c = self.d.cursor()
+            c.set_priority(db.DB_PRIORITY_VERY_LOW)  # Positional
+            self.assertEqual(db.DB_PRIORITY_VERY_LOW, c.get_priority())
+            c.set_priority(priority=db.DB_PRIORITY_HIGH)  # Keyword
+            self.assertEqual(db.DB_PRIORITY_HIGH, c.get_priority())
+            c.close()
+
     #----------------------------------------
 
     def test04_PartialGetAndPut(self):
@@ -530,7 +608,7 @@
         d = self.d
         if verbose:
             print '\n', '-=' * 30
-            print "Running %s.test99_Truncate..." % self.__class__.__name__
+            print "Running %s.test06_Truncate..." % self.__class__.__name__
 
         d.put("abcde", "ABCDE");
         num = d.truncate()
@@ -550,6 +628,33 @@
 
     #----------------------------------------
 
+    if db.version() >= (4, 6):
+        def test08_exists(self) :
+            self.d.put("abcde", "ABCDE")
+            self.assert_(self.d.exists("abcde") == True,
+                    "DB->exists() returns wrong value")
+            self.assert_(self.d.exists("x") == False,
+                    "DB->exists() returns wrong value")
+
+    #----------------------------------------
+
+    if db.version() >= (4, 7):
+        def test_compact(self) :
+            d = self.d
+            self.assertEqual(0, d.compact(flags=db.DB_FREELIST_ONLY))
+            self.assertEqual(0, d.compact(flags=db.DB_FREELIST_ONLY))
+            d.put("abcde", "ABCDE");
+            d.put("bcde", "BCDE");
+            d.put("abc", "ABC");
+            d.put("monty", "python");
+            d.delete("abc")
+            d.delete("bcde")
+            d.compact(start='abcde', stop='monty', txn=None,
+                    compact_fillpercent=42, compact_pages=1,
+                    compact_timeout=50000000,
+                    flags=db.DB_FREELIST_ONLY|db.DB_FREE_SPACE)
+
+    #----------------------------------------
 
 #----------------------------------------------------------------------
 
@@ -579,13 +684,13 @@
 
     #----------------------------------------
 
-    def test08_EnvRemoveAndRename(self):
+    def test09_EnvRemoveAndRename(self):
         if not self.env:
             return
 
         if verbose:
             print '\n', '-=' * 30
-            print "Running %s.test08_EnvRemoveAndRename..." % self.__class__.__name__
+            print "Running %s.test09_EnvRemoveAndRename..." % self.__class__.__name__
 
         # can't rename or remove an open DB
         self.d.close()
@@ -594,10 +699,6 @@
         self.env.dbrename(self.filename, None, newname)
         self.env.dbremove(newname)
 
-    # dbremove and dbrename are in 4.1 and later
-    if db.version() < (4,1):
-        del test08_EnvRemoveAndRename
-
     #----------------------------------------
 
 class BasicBTreeWithEnvTestCase(BasicWithEnvTestCase):
@@ -612,9 +713,14 @@
 
 class BasicTransactionTestCase(BasicTestCase):
     import sys
-    if sys.version_info[:3] < (2, 4, 0):
+    if sys.version_info < (2, 4):
         def assertTrue(self, expr, msg=None):
-            self.failUnless(expr,msg=msg)
+            return self.failUnless(expr,msg=msg)
+
+    if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and
+            (sys.version_info < (3, 2))) :
+        def assertIn(self, a, b, msg=None) :
+            return self.assertTrue(a in b, msg=msg)
 
     dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT
     useEnv = 1
@@ -672,10 +778,7 @@
         self.txn.commit()
 
         # flush pending updates
-        try:
-            self.env.txn_checkpoint (0, 0, 0)
-        except db.DBIncompleteError:
-            pass
+        self.env.txn_checkpoint (0, 0, 0)
 
         statDict = self.env.log_stat(0);
         self.assertIn('magic', statDict)
@@ -697,11 +800,25 @@
 
     #----------------------------------------
 
-    def test08_TxnTruncate(self):
+    if db.version() >= (4, 6):
+        def test08_exists(self) :
+            txn = self.env.txn_begin()
+            self.d.put("abcde", "ABCDE", txn=txn)
+            txn.commit()
+            txn = self.env.txn_begin()
+            self.assert_(self.d.exists("abcde", txn=txn) == True,
+                    "DB->exists() returns wrong value")
+            self.assert_(self.d.exists("x", txn=txn) == False,
+                    "DB->exists() returns wrong value")
+            txn.abort()
+
+    #----------------------------------------
+
+    def test09_TxnTruncate(self):
         d = self.d
         if verbose:
             print '\n', '-=' * 30
-            print "Running %s.test08_TxnTruncate..." % self.__class__.__name__
+            print "Running %s.test09_TxnTruncate..." % self.__class__.__name__
 
         d.put("abcde", "ABCDE");
         txn = self.env.txn_begin()
@@ -714,7 +831,7 @@
 
     #----------------------------------------
 
-    def test09_TxnLateUse(self):
+    def test10_TxnLateUse(self):
         txn = self.env.txn_begin()
         txn.abort()
         try:
@@ -734,6 +851,39 @@
             raise RuntimeError, "DBTxn.commit() called after DB_TXN no longer valid w/o an exception"
 
 
+    #----------------------------------------
+
+
+    if db.version() >= (4, 4):
+        def test_txn_name(self) :
+            txn=self.env.txn_begin()
+            self.assertEqual(txn.get_name(), "")
+            txn.set_name("XXYY")
+            self.assertEqual(txn.get_name(), "XXYY")
+            txn.set_name("")
+            self.assertEqual(txn.get_name(), "")
+            txn.abort()
+
+    #----------------------------------------
+
+
+        def test_txn_set_timeout(self) :
+            txn=self.env.txn_begin()
+            txn.set_timeout(1234567, db.DB_SET_LOCK_TIMEOUT)
+            txn.set_timeout(2345678, flags=db.DB_SET_TXN_TIMEOUT)
+            txn.abort()
+
+    #----------------------------------------
+
+    if db.version() >= (4, 2) :
+        def test_get_tx_max(self) :
+            self.assertEqual(self.env.get_tx_max(), 30)
+
+        def test_get_tx_timestamp(self) :
+            self.assertEqual(self.env.get_tx_timestamp(), self._t)
+
+
+
 class BTreeTransactionTestCase(BasicTransactionTestCase):
     dbtype = db.DB_BTREE
 
@@ -748,11 +898,11 @@
     dbtype     = db.DB_BTREE
     dbsetflags = db.DB_RECNUM
 
-    def test08_RecnoInBTree(self):
+    def test09_RecnoInBTree(self):
         d = self.d
         if verbose:
             print '\n', '-=' * 30
-            print "Running %s.test08_RecnoInBTree..." % self.__class__.__name__
+            print "Running %s.test09_RecnoInBTree..." % self.__class__.__name__
 
         rec = d.get(200)
         self.assertEqual(type(rec), type(()))
@@ -782,11 +932,11 @@
 class BasicDUPTestCase(BasicTestCase):
     dbsetflags = db.DB_DUP
 
-    def test09_DuplicateKeys(self):
+    def test10_DuplicateKeys(self):
         d = self.d
         if verbose:
             print '\n', '-=' * 30
-            print "Running %s.test09_DuplicateKeys..." % \
+            print "Running %s.test10_DuplicateKeys..." % \
                   self.__class__.__name__
 
         d.put("dup0", "before")
@@ -855,11 +1005,11 @@
         else:
             return db.DB_BTREE
 
-    def test10_MultiDB(self):
+    def test11_MultiDB(self):
         d1 = self.d
         if verbose:
             print '\n', '-=' * 30
-            print "Running %s.test10_MultiDB..." % self.__class__.__name__
+            print "Running %s.test11_MultiDB..." % self.__class__.__name__
 
         d2 = db.DB(self.env)
         d2.open(self.filename, "second", self.dbtype,
@@ -949,7 +1099,7 @@
 
 class PrivateObject(unittest.TestCase) :
     import sys
-    if sys.version_info[:3] < (2, 4, 0):
+    if sys.version_info < (2, 4):
         def assertTrue(self, expr, msg=None):
             self.failUnless(expr,msg=msg)
 
@@ -992,7 +1142,7 @@
 
 class CrashAndBurn(unittest.TestCase) :
     import sys
-    if sys.version_info[:3] < (2, 4, 0):
+    if sys.version_info < (2, 4):
         def assertTrue(self, expr, msg=None):
             self.failUnless(expr,msg=msg)
 
diff --git a/Lib/bsddb/test/test_compare.py b/Lib/bsddb/test/test_compare.py
index 4cf578b..db9cd74 100644
--- a/Lib/bsddb/test/test_compare.py
+++ b/Lib/bsddb/test/test_compare.py
@@ -12,6 +12,12 @@
         get_new_environment_path, get_new_database_path
 
 
+# Needed for python 3. "cmp" vanished in 3.0.1
+def cmp(a, b) :
+    if a==b : return 0
+    if a<b : return -1
+    return 1
+
 lexical_cmp = cmp
 
 def lowercase_cmp(left, right):
@@ -26,12 +32,16 @@
 _expected_lowercase_test_data = ['', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP']
 
 class ComparatorTests (unittest.TestCase):
+    if sys.version_info < (2, 4) :
+        def assertTrue(self, expr, msg=None) :
+            return self.failUnless(expr,msg=msg)
+
     def comparator_test_helper (self, comparator, expected_data):
         data = expected_data[:]
 
         import sys
-        if sys.version_info[:3] < (2, 6, 0):
-            if sys.version_info[:3] < (2, 4, 0):
+        if sys.version_info < (2, 6) :
+            if sys.version_info < (2, 4) :
                 data.sort(comparator)
             else :
                 data.sort(cmp=comparator)
@@ -47,7 +57,7 @@
                     data2.append(i)
             data = data2
 
-        self.assertEqual (data, expected_data,
+        self.assertEqual(data, expected_data,
                          "comparator `%s' is not right: %s vs. %s"
                          % (comparator, expected_data, data))
     def test_lexical_comparator (self):
@@ -65,6 +75,15 @@
     env = None
     db = None
 
+    if sys.version_info < (2, 4) :
+        def assertTrue(self, expr, msg=None):
+            self.failUnless(expr,msg=msg)
+
+    if (sys.version_info < (2, 7)) or ((sys.version_info >= (3,0)) and
+            (sys.version_info < (3, 2))) :
+        def assertLess(self, a, b, msg=None) :
+            return self.assertTrue(a<b, msg=msg)
+
     def setUp (self):
         self.filename = self.__class__.__name__ + '.db'
         self.homeDir = get_new_environment_path()
@@ -115,14 +134,14 @@
             rec = curs.first ()
             while rec:
                 key, ignore = rec
-                self.assertLess (index, len (expected),
+                self.assertLess(index, len (expected),
                                  "to many values returned from cursor")
-                self.assertEqual (expected[index], key,
+                self.assertEqual(expected[index], key,
                                  "expected value `%s' at %d but got `%s'"
                                  % (expected[index], index, key))
                 index = index + 1
                 rec = curs.next ()
-            self.assertEqual (index, len (expected),
+            self.assertEqual(index, len (expected),
                              "not enough values returned from cursor")
         finally:
             curs.close ()
@@ -193,7 +212,8 @@
             errorOut = temp.getvalue()
             if not successRe.search(errorOut):
                 self.fail("unexpected stderr output:\n"+errorOut)
-        sys.exc_traceback = sys.last_traceback = None
+        if sys.version_info < (3, 0) :  # XXX: How to do this in Py3k ???
+            sys.exc_traceback = sys.last_traceback = None
 
     def _test_compare_function_exception (self):
         self.startTest ()
@@ -237,8 +257,8 @@
         def my_compare (a, b):
             return 0
 
-        self.startTest ()
-        self.createDB (my_compare)
+        self.startTest()
+        self.createDB(my_compare)
         self.assertRaises (RuntimeError, self.db.set_bt_compare, my_compare)
 
 def test_suite ():
diff --git a/Lib/bsddb/test/test_dbshelve.py b/Lib/bsddb/test/test_dbshelve.py
index 13f9cd2..7ad1fd1 100644
--- a/Lib/bsddb/test/test_dbshelve.py
+++ b/Lib/bsddb/test/test_dbshelve.py
@@ -2,10 +2,9 @@
 TestCases for checking dbShelve objects.
 """
 
-import os, string
+import os, string, sys
 import random
 import unittest
-import warnings
 
 
 from test_all import db, dbshelve, test_support, verbose, \
@@ -13,6 +12,11 @@
 
 
 
+if sys.version_info < (2, 4) :
+    from sets import Set as set
+
+
+
 #----------------------------------------------------------------------
 
 # We want the objects to be comparable so we can test dbshelve.values
@@ -29,8 +33,17 @@
 
 
 class DBShelveTestCase(unittest.TestCase):
+    if sys.version_info < (2, 4):
+        def assertTrue(self, expr, msg=None):
+            return self.failUnless(expr,msg=msg)
+
+    if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and
+            (sys.version_info < (3, 2))) :
+        def assertIn(self, a, b, msg=None) :
+            return self.assertTrue(a in b, msg=msg)
+
+
     def setUp(self):
-        import sys
         if sys.version_info[0] >= 3 :
             from test_all import do_proxy_db_py3k
             self._flag_proxy_db_py3k = do_proxy_db_py3k(False)
@@ -38,7 +51,6 @@
         self.do_open()
 
     def tearDown(self):
-        import sys
         if sys.version_info[0] >= 3 :
             from test_all import do_proxy_db_py3k
             do_proxy_db_py3k(self._flag_proxy_db_py3k)
@@ -48,7 +60,6 @@
     def mk(self, key):
         """Turn key into an appropriate key type for this db"""
         # override in child class for RECNO
-        import sys
         if sys.version_info[0] < 3 :
             return key
         else :
@@ -118,11 +129,14 @@
 
         dbvalues = d.values()
         self.assertEqual(len(dbvalues), len(d.keys()))
-        with warnings.catch_warnings():
-            warnings.filterwarnings('ignore',
-                                    'comparing unequal types not supported',
-                                    DeprecationWarning)
-            self.assertEqual(sorted(values), sorted(dbvalues))
+        if sys.version_info < (2, 6) :
+            values.sort()
+            dbvalues.sort()
+            self.assertEqual(values, dbvalues)
+        else :  # XXX: Convert all to strings. Please, improve
+            values.sort(key=lambda x : str(x))
+            dbvalues.sort(key=lambda x : str(x))
+            self.assertEqual(repr(values), repr(dbvalues))
 
         items = d.items()
         self.assertEqual(len(items), len(values))
@@ -197,10 +211,21 @@
                           self.d.append, 'unit test was here')
 
 
+    def test04_iterable(self) :
+        self.populateDB(self.d)
+        d = self.d
+        keys = d.keys()
+        keyset = set(keys)
+        self.assertEqual(len(keyset), len(keys))
+
+        for key in d :
+            self.assertIn(key, keyset)
+            keyset.remove(key)
+        self.assertEqual(len(keyset), 0)
+
     def checkrec(self, key, value):
         # override this in a subclass if the key type is different
 
-        import sys
         if sys.version_info[0] >= 3 :
             if isinstance(key, bytes) :
                 key = key.decode("iso8859-1")  # 8 bits
@@ -219,7 +244,6 @@
             self.assertEqual(value, [x] * 10)
 
         elif key[0] == 'O':
-            import sys
             if sys.version_info[0] < 3 :
                 from types import InstanceType
                 self.assertEqual(type(value), InstanceType)
@@ -287,7 +311,6 @@
         DBShelveTestCase.setUp(self)
 
     def tearDown(self):
-        import sys
         if sys.version_info[0] >= 3 :
             from test_all import do_proxy_db_py3k
             do_proxy_db_py3k(self._flag_proxy_db_py3k)
diff --git a/Lib/bsddb/test/test_dbtables.py b/Lib/bsddb/test/test_dbtables.py
index 935c9d5..c6ecc13 100644
--- a/Lib/bsddb/test/test_dbtables.py
+++ b/Lib/bsddb/test/test_dbtables.py
@@ -20,11 +20,15 @@
 #
 # $Id$
 
-import os, re
-try:
-    import cPickle
-    pickle = cPickle
-except ImportError:
+import os, re, sys
+
+if sys.version_info[0] < 3 :
+    try:
+        import cPickle
+        pickle = cPickle
+    except ImportError:
+        import pickle
+else :
     import pickle
 
 import unittest
diff --git a/Lib/bsddb/test/test_distributed_transactions.py b/Lib/bsddb/test/test_distributed_transactions.py
index c6243a2..a36bd66 100644
--- a/Lib/bsddb/test/test_distributed_transactions.py
+++ b/Lib/bsddb/test/test_distributed_transactions.py
@@ -37,7 +37,7 @@
         self.db = db.DB(self.dbenv)
         self.db.set_re_len(db.DB_GID_SIZE)
         if must_open_db :
-            if db.version() > (4,1) :
+            if db.version() >= (4,2) :
                 txn=self.dbenv.txn_begin()
                 self.db.open(self.filename,
                         db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0666,
diff --git a/Lib/bsddb/test/test_early_close.py b/Lib/bsddb/test/test_early_close.py
index cc69e47..e0c1e1d 100644
--- a/Lib/bsddb/test/test_early_close.py
+++ b/Lib/bsddb/test/test_early_close.py
@@ -2,7 +2,7 @@
 is closed before its DB objects.
 """
 
-import os
+import os, sys
 import unittest
 
 from test_all import db, test_support, verbose, get_new_environment_path, get_new_database_path
@@ -155,22 +155,43 @@
                 db.DB_INIT_LOG | db.DB_CREATE)
         d = db.DB(dbenv)
         txn = dbenv.txn_begin()
-        if db.version() < (4,1) :
-            d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE)
-        else :
-            d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE,
-                    txn=txn)
+        d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE,
+                txn=txn)
         d.put("XXX", "yyy", txn=txn)
         txn.commit()
         txn = dbenv.txn_begin()
         c1 = d.cursor(txn)
         c2 = c1.dup()
         self.assertEquals(("XXX", "yyy"), c1.first())
-        import warnings
+
         # Not interested in warnings about implicit close.
-        with warnings.catch_warnings():
+        import warnings
+        if sys.version_info < (2, 6) :
+            # Completely resetting the warning state is
+            # problematic with python >=2.6 with -3 (py3k warning),
+            # because some stdlib modules selectively ignores warnings.
             warnings.simplefilter("ignore")
             txn.commit()
+            warnings.resetwarnings()
+        else :
+            # When we drop support for python 2.3 and 2.4
+            # we could use: (in 2.5 we need a __future__ statement)
+            #
+            #    with warnings.catch_warnings():
+            #        warnings.simplefilter("ignore")
+            #        txn.commit()
+            #
+            # We can not use "with" as is, because it would be invalid syntax
+            # in python 2.3, 2.4 and (with no __future__) 2.5.
+            # Here we simulate "with" following PEP 343 :
+            w = warnings.catch_warnings()
+            w.__enter__()
+            try :
+                warnings.simplefilter("ignore")
+                txn.commit()
+            finally :
+                w.__exit__()
+
         self.assertRaises(db.DBCursorClosedError, c2.first)
 
     if db.version() > (4,3,0) :
diff --git a/Lib/bsddb/test/test_lock.py b/Lib/bsddb/test/test_lock.py
index 47da392..25260fc 100644
--- a/Lib/bsddb/test/test_lock.py
+++ b/Lib/bsddb/test/test_lock.py
@@ -20,7 +20,7 @@
 
 class LockingTestCase(unittest.TestCase):
     import sys
-    if sys.version_info[:3] < (2, 4, 0):
+    if sys.version_info < (2, 4) :
         def assertTrue(self, expr, msg=None):
             self.failUnless(expr,msg=msg)
 
@@ -89,7 +89,18 @@
         for t in threads:
             t.join()
 
-    def test03_lock_timeout(self):
+    if db.version() >= (4, 2) :
+        def test03_lock_timeout(self):
+            self.env.set_timeout(0, db.DB_SET_LOCK_TIMEOUT)
+            self.assertEqual(self.env.get_timeout(db.DB_SET_LOCK_TIMEOUT), 0)
+            self.env.set_timeout(0, db.DB_SET_TXN_TIMEOUT)
+            self.assertEqual(self.env.get_timeout(db.DB_SET_TXN_TIMEOUT), 0)
+            self.env.set_timeout(123456, db.DB_SET_LOCK_TIMEOUT)
+            self.assertEqual(self.env.get_timeout(db.DB_SET_LOCK_TIMEOUT), 123456)
+            self.env.set_timeout(7890123, db.DB_SET_TXN_TIMEOUT)
+            self.assertEqual(self.env.get_timeout(db.DB_SET_TXN_TIMEOUT), 7890123)
+
+    def test04_lock_timeout2(self):
         self.env.set_timeout(0, db.DB_SET_LOCK_TIMEOUT)
         self.env.set_timeout(0, db.DB_SET_TXN_TIMEOUT)
         self.env.set_timeout(123456, db.DB_SET_LOCK_TIMEOUT)
@@ -124,6 +135,7 @@
                 self.env.lock_get,anID2, "shared lock", db.DB_LOCK_READ)
         end_time=time.time()
         deadlock_detection.end=True
+        # Floating point rounding
         self.assertTrue((end_time-start_time) >= 0.0999)
         self.env.lock_put(lock)
         t.join()
diff --git a/Lib/bsddb/test/test_misc.py b/Lib/bsddb/test/test_misc.py
index 0cf75e9..7b111a8 100644
--- a/Lib/bsddb/test/test_misc.py
+++ b/Lib/bsddb/test/test_misc.py
@@ -1,7 +1,7 @@
 """Miscellaneous bsddb module test cases
 """
 
-import os
+import os, sys
 import unittest
 
 from test_all import db, dbshelve, hashopen, test_support, get_new_environment_path, get_new_database_path
@@ -9,6 +9,13 @@
 #----------------------------------------------------------------------
 
 class MiscTestCase(unittest.TestCase):
+    if sys.version_info < (2, 4) :
+        def assertTrue(self, expr, msg=None):
+            self.failUnless(expr, msg=msg)
+
+        def assertFalse(self, expr, msg=None):
+            self.failIf(expr, msg=msg)
+
     def setUp(self):
         self.filename = get_new_database_path()
         self.homeDir = get_new_environment_path()
@@ -27,7 +34,6 @@
         # check for crash fixed when db_home is used before open()
         self.assert_(env.db_home is None)
         env.open(self.homeDir, db.DB_CREATE)
-        import sys
         if sys.version_info[0] < 3 :
             self.assertEqual(self.homeDir, env.db_home)
         else :
@@ -119,6 +125,19 @@
             test_support.unlink(self.filename)
 
 
+    def test08_ExceptionTypes(self) :
+        self.assertTrue(issubclass(db.DBError, Exception))
+        for i, j in db.__dict__.items() :
+            if i.startswith("DB") and i.endswith("Error") :
+                self.assertTrue(issubclass(j, db.DBError), msg=i)
+                if i not in ("DBKeyEmptyError", "DBNotFoundError") :
+                    self.assertFalse(issubclass(j, KeyError), msg=i)
+
+        # This two exceptions have two bases
+        self.assertTrue(issubclass(db.DBKeyEmptyError, KeyError))
+        self.assertTrue(issubclass(db.DBNotFoundError, KeyError))
+
+
 #----------------------------------------------------------------------
 
 
diff --git a/Lib/bsddb/test/test_pickle.py b/Lib/bsddb/test/test_pickle.py
index 489c093..6a8478d 100644
--- a/Lib/bsddb/test/test_pickle.py
+++ b/Lib/bsddb/test/test_pickle.py
@@ -1,10 +1,16 @@
 
 import os
 import pickle
-try:
-    import cPickle
-except ImportError:
+import sys
+
+if sys.version_info[0] < 3 :
+    try:
+        import cPickle
+    except ImportError:
+        cPickle = None
+else :
     cPickle = None
+
 import unittest
 
 from test_all import db, test_support, get_new_environment_path, get_new_database_path
diff --git a/Lib/bsddb/test/test_recno.py b/Lib/bsddb/test/test_recno.py
index 0a10ec9..f86a28b 100644
--- a/Lib/bsddb/test/test_recno.py
+++ b/Lib/bsddb/test/test_recno.py
@@ -1,7 +1,7 @@
 """TestCases for exercising a Recno DB.
 """
 
-import os
+import os, sys
 import errno
 from pprint import pprint
 import unittest
@@ -14,10 +14,19 @@
 #----------------------------------------------------------------------
 
 class SimpleRecnoTestCase(unittest.TestCase):
-    import sys
-    if sys.version_info[:3] < (2, 4, 0):
-        def assertFalse(self, expr, msg=None):
-            self.failIf(expr,msg=msg)
+    if sys.version_info < (2, 4) :
+        def assertFalse(self, expr, msg=None) :
+            return self.failIf(expr,msg=msg)
+        def assertTrue(self, expr, msg=None) :
+            return self.assert_(expr, msg=msg)
+
+    if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and
+            (sys.version_info < (3, 2))) :
+        def assertIsInstance(self, obj, datatype, msg=None) :
+            return self.assertEqual(type(obj), datatype, msg=msg)
+        def assertGreaterEqual(self, a, b, msg=None) :
+            return self.assertTrue(a>=b, msg=msg)
+
 
     def setUp(self):
         self.filename = get_new_database_path()
@@ -60,7 +69,10 @@
         try:
             data = d[0]  # This should raise a KeyError!?!?!
         except db.DBInvalidArgError, val:
-            self.assertEqual(val.args[0], db.EINVAL)
+            if sys.version_info < (2, 6) :
+                self.assertEqual(val[0], db.EINVAL)
+            else :
+                self.assertEqual(val.args[0], db.EINVAL)
             if verbose: print val
         else:
             self.fail("expected exception")
@@ -177,7 +189,10 @@
             if get_returns_none:
                 self.fail("unexpected DBKeyEmptyError exception")
             else:
-                self.assertEqual(val.args[0], db.DB_KEYEMPTY)
+                if sys.version_info < (2, 6) :
+                    self.assertEqual(val[0], db.DB_KEYEMPTY)
+                else :
+                    self.assertEqual(val.args[0], db.DB_KEYEMPTY)
                 if verbose: print val
         else:
             if not get_returns_none:
@@ -265,7 +280,10 @@
         try:                    # this one will fail
             d.append('bad' * 20)
         except db.DBInvalidArgError, val:
-            self.assertEqual(val.args[0], db.EINVAL)
+            if sys.version_info < (2, 6) :
+                self.assertEqual(val[0], db.EINVAL)
+            else :
+                self.assertEqual(val.args[0], db.EINVAL)
             if verbose: print val
         else:
             self.fail("expected exception")
diff --git a/Lib/bsddb/test/test_replication.py b/Lib/bsddb/test/test_replication.py
index fabc165..9ed2126 100644
--- a/Lib/bsddb/test/test_replication.py
+++ b/Lib/bsddb/test/test_replication.py
@@ -4,7 +4,6 @@
 import os
 import time
 import unittest
-import weakref
 
 from test_all import db, test_support, have_threads, verbose, \
         get_new_environment_path, get_new_database_path
@@ -12,9 +11,9 @@
 
 #----------------------------------------------------------------------
 
-class DBReplicationManager(unittest.TestCase):
+class DBReplication(unittest.TestCase) :
     import sys
-    if sys.version_info[:3] < (2, 4, 0):
+    if sys.version_info < (2, 4) :
         def assertTrue(self, expr, msg=None):
             self.failUnless(expr,msg=msg)
 
@@ -35,16 +34,13 @@
                 | db.DB_INIT_LOG | db.DB_INIT_MPOOL | db.DB_INIT_LOCK |
                 db.DB_INIT_REP | db.DB_RECOVER | db.DB_THREAD, 0666)
 
-        wr = weakref.ref(self)
         self.confirmed_master=self.client_startupdone=False
         def confirmed_master(a,b,c) :
             if b==db.DB_EVENT_REP_MASTER :
-                self = wr()
                 self.confirmed_master=True
 
         def client_startupdone(a,b,c) :
             if b==db.DB_EVENT_REP_STARTUPDONE :
-                self = wr()
                 self.client_startupdone=True
 
         self.dbenvMaster.set_event_notify(confirmed_master)
@@ -63,11 +59,21 @@
             self.dbClient.close()
         if self.dbMaster :
             self.dbMaster.close()
+
+        # Here we assign dummy event handlers to allow GC of the test object.
+        # Since the dummy handler doesn't use any outer scope variable, it
+        # doesn't keep any reference to the test object.
+        def dummy(*args) :
+            pass
+        self.dbenvMaster.set_event_notify(dummy)
+        self.dbenvClient.set_event_notify(dummy)
+
         self.dbenvClient.close()
         self.dbenvMaster.close()
         test_support.rmtree(self.homeDirClient)
         test_support.rmtree(self.homeDirMaster)
 
+class DBReplicationManager(DBReplication) :
     def test01_basic_replication(self) :
         master_port = test_support.find_unused_port()
         self.dbenvMaster.repmgr_set_local_site("127.0.0.1", master_port)
@@ -216,18 +222,15 @@
         self.assertTrue(time.time()<timeout)
         self.assertEquals(None, v)
 
-class DBBaseReplication(DBReplicationManager):
+class DBBaseReplication(DBReplication) :
     def setUp(self) :
-        DBReplicationManager.setUp(self)
-        wr = weakref.ref(self)
+        DBReplication.setUp(self)
         def confirmed_master(a,b,c) :
             if (b == db.DB_EVENT_REP_MASTER) or (b == db.DB_EVENT_REP_ELECTED) :
-                self = wr()
                 self.confirmed_master = True
 
         def client_startupdone(a,b,c) :
             if b == db.DB_EVENT_REP_STARTUPDONE :
-                self = wr()
                 self.client_startupdone = True
 
         self.dbenvMaster.set_event_notify(confirmed_master)
@@ -240,11 +243,9 @@
         # There are only two nodes, so we don't need to
         # do any routing decision
         def m2c(dbenv, control, rec, lsnp, envid, flags) :
-            self = wr()
             self.m2c.put((control, rec))
 
         def c2m(dbenv, control, rec, lsnp, envid, flags) :
-            self = wr()
             self.c2m.put((control, rec))
 
         self.dbenvMaster.rep_set_transport(13,m2c)
@@ -261,12 +262,10 @@
         #self.dbenvClient.set_verbose(db.DB_VERB_FILEOPS_ALL, True)
 
         def thread_master() :
-            self = wr()
             return self.thread_do(self.dbenvMaster, self.c2m, 3,
                     self.master_doing_election, True)
 
         def thread_client() :
-            self = wr()
             return self.thread_do(self.dbenvClient, self.m2c, 13,
                     self.client_doing_election, False)
 
@@ -299,6 +298,17 @@
         self.c2m.put(None)
         self.t_m.join()
         self.t_c.join()
+
+        # Here we assign dummy event handlers to allow GC of the test object.
+        # Since the dummy handler doesn't use any outer scope variable, it
+        # doesn't keep any reference to the test object.
+        def dummy(*args) :
+            pass
+        self.dbenvMaster.set_event_notify(dummy)
+        self.dbenvClient.set_event_notify(dummy)
+        self.dbenvMaster.rep_set_transport(13,dummy)
+        self.dbenvClient.rep_set_transport(3,dummy)
+
         self.dbenvClient.close()
         self.dbenvMaster.close()
         test_support.rmtree(self.homeDirClient)
@@ -358,6 +368,9 @@
             txn.commit()
             break
 
+        d = self.dbenvMaster.rep_stat(flags=db.DB_STAT_CLEAR);
+        self.assertTrue("master_changes" in d)
+
         txn=self.dbenvMaster.txn_begin()
         self.dbMaster.put("ABC", "123", txn=txn)
         txn.commit()
@@ -419,7 +432,6 @@
                                     break
                                 except db.DBRepUnavailError :
                                     pass
-
                         if not election_status[0] and not self.confirmed_master :
                             from threading import Thread
                             election_status[0] = True
@@ -449,6 +461,14 @@
 
             self.assertTrue(self.confirmed_master)
 
+    if db.version() >= (4,7) :
+        def test04_test_clockskew(self) :
+            fast, slow = 1234, 1230
+            self.dbenvMaster.rep_set_clockskew(fast, slow)
+            self.assertEqual((fast, slow),
+                    self.dbenvMaster.rep_get_clockskew())
+            self.basic_rep_threading()
+
 #----------------------------------------------------------------------
 
 def test_suite():
diff --git a/Lib/bsddb/test/test_sequence.py b/Lib/bsddb/test/test_sequence.py
index b61ead4..cad598b 100644
--- a/Lib/bsddb/test/test_sequence.py
+++ b/Lib/bsddb/test/test_sequence.py
@@ -6,7 +6,7 @@
 
 class DBSequenceTest(unittest.TestCase):
     import sys
-    if sys.version_info[:3] < (2, 4, 0):
+    if sys.version_info < (2, 4) :
         def assertTrue(self, expr, msg=None):
             self.failUnless(expr,msg=msg)
 
@@ -37,7 +37,7 @@
         self.seq = db.DBSequence(self.d, flags=0)
         start_value = 10 * self.int_32_max
         self.assertEqual(0xA00000000, start_value)
-        self.assertEquals(None, self.seq.init_value(start_value))
+        self.assertEquals(None, self.seq.initial_value(start_value))
         self.assertEquals(None, self.seq.open(key='id', txn=None, flags=db.DB_CREATE))
         self.assertEquals(start_value, self.seq.get(5))
         self.assertEquals(start_value + 5, self.seq.get())
@@ -77,7 +77,7 @@
         self.seq = db.DBSequence(self.d, flags=0)
         seq_range = (10 * self.int_32_max, 11 * self.int_32_max - 1)
         self.assertEquals(None, self.seq.set_range(seq_range))
-        self.seq.init_value(seq_range[0])
+        self.seq.initial_value(seq_range[0])
         self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
         self.assertEquals(seq_range, self.seq.get_range())
 
@@ -110,7 +110,7 @@
         value_minus=(-1L<<63)+1  # Two complement
         self.assertEquals(-9223372036854775807L,value_minus)
         self.seq = db.DBSequence(self.d, flags=0)
-        self.assertEquals(None, self.seq.init_value(value_plus-1))
+        self.assertEquals(None, self.seq.initial_value(value_plus-1))
         self.assertEquals(None, self.seq.open(key='id', txn=None,
             flags=db.DB_CREATE))
         self.assertEquals(value_plus-1, self.seq.get(1))
@@ -119,7 +119,7 @@
         self.seq.remove(txn=None, flags=0)
 
         self.seq = db.DBSequence(self.d, flags=0)
-        self.assertEquals(None, self.seq.init_value(value_minus))
+        self.assertEquals(None, self.seq.initial_value(value_minus))
         self.assertEquals(None, self.seq.open(key='id', txn=None,
             flags=db.DB_CREATE))
         self.assertEquals(value_minus, self.seq.get(1))
diff --git a/Lib/bsddb/test/test_thread.py b/Lib/bsddb/test/test_thread.py
index 28a2555..91002b8 100644
--- a/Lib/bsddb/test/test_thread.py
+++ b/Lib/bsddb/test/test_thread.py
@@ -21,7 +21,6 @@
 
 if have_threads :
     from threading import Thread
-    import sys
     if sys.version_info[0] < 3 :
         from threading import currentThread
     else :
@@ -36,8 +35,7 @@
     dbsetflags   = 0
     envflags     = 0
 
-    import sys
-    if sys.version_info[:3] < (2, 4, 0):
+    if sys.version_info < (2, 4) :
         def assertTrue(self, expr, msg=None):
             self.failUnless(expr,msg=msg)
 
@@ -99,7 +97,6 @@
                         args = (self.d, x),
                         name = 'reader %d' % x,
                         )#verbose = verbose)
-            import sys
             if sys.version_info[0] < 3 :
                 rt.setDaemon(True)
             else :
@@ -118,7 +115,6 @@
             writers.append(wt)
 
         for t in writers:
-            import sys
             if sys.version_info[0] < 3 :
                 t.setDaemon(True)
             else :
@@ -131,7 +127,6 @@
             t.join()
 
     def writerThread(self, d, keys, readers):
-        import sys
         if sys.version_info[0] < 3 :
             name = currentThread().getName()
         else :
@@ -161,7 +156,6 @@
             print "%s: thread finished" % name
 
     def readerThread(self, d, readerNum):
-        import sys
         if sys.version_info[0] < 3 :
             name = currentThread().getName()
         else :
@@ -231,7 +225,6 @@
                         args = (self.d, x),
                         name = 'reader %d' % x,
                         )#verbose = verbose)
-            import sys
             if sys.version_info[0] < 3 :
                 rt.setDaemon(True)
             else :
@@ -250,7 +243,6 @@
             writers.append(wt)
 
         for t in writers:
-            import sys
             if sys.version_info[0] < 3 :
                 t.setDaemon(True)
             else :
@@ -263,7 +255,6 @@
             t.join()
 
     def writerThread(self, d, keys, readers):
-        import sys
         if sys.version_info[0] < 3 :
             name = currentThread().getName()
         else :
@@ -290,7 +281,6 @@
             print "%s: thread finished" % name
 
     def readerThread(self, d, readerNum):
-        import sys
         if sys.version_info[0] < 3 :
             name = currentThread().getName()
         else :
@@ -361,7 +351,6 @@
                         args = (self.d, x),
                         name = 'reader %d' % x,
                         )#verbose = verbose)
-            import sys
             if sys.version_info[0] < 3 :
                 rt.setDaemon(True)
             else :
@@ -379,7 +368,6 @@
             writers.append(wt)
 
         dt = Thread(target = self.deadlockThread)
-        import sys
         if sys.version_info[0] < 3 :
             dt.setDaemon(True)
         else :
@@ -387,7 +375,6 @@
         dt.start()
 
         for t in writers:
-            import sys
             if sys.version_info[0] < 3 :
                 t.setDaemon(True)
             else :
@@ -403,7 +390,6 @@
         dt.join()
 
     def writerThread(self, d, keys, readers):
-        import sys
         if sys.version_info[0] < 3 :
             name = currentThread().getName()
         else :
@@ -424,14 +410,17 @@
                 readers.pop().start()
             except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val:
                 if verbose:
-                    print "%s: Aborting transaction (%s)" % (name, val.args[1])
+                    if sys.version_info < (2, 6) :
+                        print "%s: Aborting transaction (%s)" % (name, val[1])
+                    else :
+                        print "%s: Aborting transaction (%s)" % (name,
+                                val.args[1])
                 txn.abort()
 
         if verbose:
             print "%s: thread finished" % name
 
     def readerThread(self, d, readerNum):
-        import sys
         if sys.version_info[0] < 3 :
             name = currentThread().getName()
         else :
@@ -455,7 +444,11 @@
                 finished = True
             except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val:
                 if verbose:
-                    print "%s: Aborting transaction (%s)" % (name, val.args[1])
+                    if sys.version_info < (2, 6) :
+                        print "%s: Aborting transaction (%s)" % (name, val[1])
+                    else :
+                        print "%s: Aborting transaction (%s)" % (name,
+                                val.args[1])
                 c.close()
                 txn.abort()