[Python-checkins] r65193 - in python/trunk: Lib/bsddb/__init__.py Lib/bsddb/db.py Lib/bsddb/dbobj.py Lib/bsddb/dbshelve.py Lib/bsddb/dbtables.py Lib/bsddb/dbutils.py Lib/bsddb/test/test_all.py Lib/bsddb/test/test_associate.py Lib/bsddb/test/test_basics.py Lib/bsddb/test/test_compare.py Lib/bsddb/test/test_lock.py Lib/bsddb/test/test_misc.py Lib/bsddb/test/test_replication.py Lib/bsddb/test/test_thread.py Modules/_bsddb.c Modules/bsddb.h

jesus.cea python-checkins at python.org
Wed Jul 23 13:38:43 CEST 2008


Author: jesus.cea
Date: Wed Jul 23 13:38:42 2008
New Revision: 65193
Log:
bsddb module updated to version 4.7.2devel9.
This patch publishes the work done until now
for Python 3.0 compatibility. Still a lot
to be done.
When possible, we use 3.0 features in Python 2.6,
easing development and testing, and exposing internal
changes to a wider audience, for better test coverage.
Some mode details:
http://www.jcea.es/programacion/pybsddb.htm#bsddb3-4.7.2
Modified:
 python/trunk/Lib/bsddb/__init__.py
 python/trunk/Lib/bsddb/db.py
 python/trunk/Lib/bsddb/dbobj.py
 python/trunk/Lib/bsddb/dbshelve.py
 python/trunk/Lib/bsddb/dbtables.py
 python/trunk/Lib/bsddb/dbutils.py
 python/trunk/Lib/bsddb/test/test_all.py
 python/trunk/Lib/bsddb/test/test_associate.py
 python/trunk/Lib/bsddb/test/test_basics.py
 python/trunk/Lib/bsddb/test/test_compare.py
 python/trunk/Lib/bsddb/test/test_lock.py
 python/trunk/Lib/bsddb/test/test_misc.py
 python/trunk/Lib/bsddb/test/test_replication.py
 python/trunk/Lib/bsddb/test/test_thread.py
 python/trunk/Modules/_bsddb.c
 python/trunk/Modules/bsddb.h
Modified: python/trunk/Lib/bsddb/__init__.py
==============================================================================
--- python/trunk/Lib/bsddb/__init__.py	(original)
+++ python/trunk/Lib/bsddb/__init__.py	Wed Jul 23 13:38:42 2008
@@ -33,18 +33,25 @@
 #----------------------------------------------------------------------
 
 
-"""Support for Berkeley DB 4.x with a simple interface.
+"""Support for Berkeley DB 4.0 through 4.7 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.
 """
 
+import sys
+absolute_import = (sys.version_info[0] >= 3)
+
 try:
 if __name__ == 'bsddb3':
 # import _pybsddb binary as it should be the more recent version from
 # a standalone pybsddb addon package than the version included with
 # python as bsddb._bsddb.
- import _pybsddb
+ if absolute_import :
+ # Because this syntaxis is not valid before Python 2.5
+ exec("from . import _pybsddb")
+ else :
+ import _pybsddb
 _bsddb = _pybsddb
 from bsddb3.dbutils import DeadlockWrap as _DeadlockWrap
 else:
@@ -66,9 +73,16 @@
 
 import sys, os
 
-import UserDict
 from weakref import ref
-class _iter_mixin(UserDict.DictMixin):
+
+if sys.version_info[0:2] <= (2, 5) :
+ import UserDict
+ MutableMapping = UserDict.DictMixin
+else :
+ import collections
+ MutableMapping = collections.MutableMapping
+
+class _iter_mixin(MutableMapping):
 def _make_iter_cursor(self):
 cur = _DeadlockWrap(self.db.cursor)
 key = id(cur)
@@ -115,8 +129,12 @@
 except _bsddb.DBCursorClosedError:
 # the database was modified during iteration. abort.
 pass
- finally:
+# When Python 2.3 not supported in bsddb3, we can change this to "finally"
+ except :
 self._in_iter -= 1
+ raise
+
+ self._in_iter -= 1
 
 def iteritems(self):
 if not self.db:
@@ -154,8 +172,12 @@
 except _bsddb.DBCursorClosedError:
 # the database was modified during iteration. abort.
 pass
- finally:
+# When Python 2.3 not supported in bsddb3, we can change this to "finally"
+ except :
 self._in_iter -= 1
+ raise
+
+ self._in_iter -= 1
 
 
 class _DBWithCursor(_iter_mixin):
@@ -228,6 +250,12 @@
 self._checkOpen()
 return _DeadlockWrap(lambda: len(self.db)) # len(self.db)
 
+ if sys.version_info[0:2] >= (2, 6) :
+ def __repr__(self) :
+ if self.isOpen() :
+ return repr(dict(_DeadlockWrap(self.db.items)))
+ return repr(dict())
+
 def __getitem__(self, key):
 self._checkOpen()
 return _DeadlockWrap(lambda: self.db[key]) # self.db[key]
@@ -407,8 +435,6 @@
 try:
 import thread
 del thread
- if db.version() < (3, 3, 0):
- db.DB_THREAD = 0
 except ImportError:
 db.DB_THREAD = 0
 
Modified: python/trunk/Lib/bsddb/db.py
==============================================================================
--- python/trunk/Lib/bsddb/db.py	(original)
+++ python/trunk/Lib/bsddb/db.py	Wed Jul 23 13:38:42 2008
@@ -37,15 +37,24 @@
 # case we ever want to augment the stuff in _db in any way. For now
 # it just simply imports everything from _db.
 
-if __name__.startswith('bsddb3.'):
- # import _pybsddb binary as it should be the more recent version from
- # a standalone pybsddb addon package than the version included with
- # python as bsddb._bsddb.
- from _pybsddb import *
- from _pybsddb import __version__
-else:
- from _bsddb import *
- from _bsddb import __version__
+import sys
+absolute_import = (sys.version_info[0] >= 3)
 
-if version() < (3, 2, 0):
- raise ImportError, "correct Berkeley DB symbols not found. Perhaps python was statically linked with an older version?"
+if not absolute_import :
+ if __name__.startswith('bsddb3.') :
+ # import _pybsddb binary as it should be the more recent version from
+ # a standalone pybsddb addon package than the version included with
+ # python as bsddb._bsddb.
+ from _pybsddb import *
+ from _pybsddb import __version__
+ else:
+ from _bsddb import *
+ from _bsddb import __version__
+else :
+ # Because this syntaxis is not valid before Python 2.5
+ if __name__.startswith('bsddb3.') :
+ exec("from ._pybsddb import *")
+ exec("from ._pybsddb import __version__")
+ else :
+ exec("from ._bsddb import *")
+ exec("from ._bsddb import __version__")
Modified: python/trunk/Lib/bsddb/dbobj.py
==============================================================================
--- python/trunk/Lib/bsddb/dbobj.py	(original)
+++ python/trunk/Lib/bsddb/dbobj.py	Wed Jul 23 13:38:42 2008
@@ -21,13 +21,24 @@
 # added to _bsddb.c.
 #
 
-import db
-
-try:
- from UserDict import DictMixin
-except ImportError:
- # DictMixin is new in Python 2.3
- class DictMixin: pass
+import sys
+absolute_import = (sys.version_info[0] >= 3)
+if absolute_import :
+ # Because this syntaxis is not valid before Python 2.5
+ exec("from . import db")
+else :
+ import db
+
+if sys.version_info[0:2] <= (2, 5) :
+ 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
 
 class DBEnv:
 def __init__(self, *args, **kwargs):
@@ -96,9 +107,8 @@
 def set_get_returns_none(self, *args, **kwargs):
 return apply(self._cobj.set_get_returns_none, args, kwargs)
 
- if db.version() >= (4,0):
- def log_stat(self, *args, **kwargs):
- return apply(self._cobj.log_stat, args, kwargs)
+ def log_stat(self, *args, **kwargs):
+ return apply(self._cobj.log_stat, args, kwargs)
 
 if db.version() >= (4,1):
 def dbremove(self, *args, **kwargs):
@@ -113,7 +123,7 @@
 return apply(self._cobj.lsn_reset, args, kwargs)
 
 
-class DB(DictMixin):
+class DB(MutableMapping):
 def __init__(self, dbenv, *args, **kwargs):
 # give it the proper DBEnv C object that its expecting
 self._cobj = apply(db.DB, (dbenv._cobj,) + args, kwargs)
@@ -128,6 +138,10 @@
 def __delitem__(self, arg):
 del self._cobj[arg]
 
+ if sys.version_info[0:2] >= (2, 6) :
+ def __iter__(self) :
+ return self._cobj.__iter__()
+
 def append(self, *args, **kwargs):
 return apply(self._cobj.append, args, kwargs)
 def associate(self, *args, **kwargs):
Modified: python/trunk/Lib/bsddb/dbshelve.py
==============================================================================
--- python/trunk/Lib/bsddb/dbshelve.py	(original)
+++ python/trunk/Lib/bsddb/dbshelve.py	Wed Jul 23 13:38:42 2008
@@ -30,11 +30,17 @@
 #------------------------------------------------------------------------
 
 import cPickle
-import db
 import sys
 
-#At version 2.3 cPickle switched to using protocol instead of bin and
-#DictMixin was added
+import sys
+absolute_import = (sys.version_info[0] >= 3)
+if absolute_import :
+ # Because this syntaxis is not valid before Python 2.5
+ exec("from . import db")
+else :
+ import db
+
+#At version 2.3 cPickle switched to using protocol instead of bin
 if sys.version_info[:3] >= (2, 3, 0):
 HIGHEST_PROTOCOL = cPickle.HIGHEST_PROTOCOL
 # In python 2.3.*, "cPickle.dumps" accepts no
@@ -47,13 +53,22 @@
 def _dumps(object, protocol):
 return cPickle.dumps(object, protocol=protocol)
 
- from UserDict import DictMixin
-
 else:
 HIGHEST_PROTOCOL = None
 def _dumps(object, protocol):
 return cPickle.dumps(object, bin=protocol)
- class DictMixin: pass
+
+
+if sys.version_info[0:2] <= (2, 5) :
+ 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
 
 #------------------------------------------------------------------------
 
@@ -96,7 +111,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.
 """
@@ -147,6 +162,10 @@
 else:
 return self.db.keys()
 
+ if sys.version_info[0:2] >= (2, 6) :
+ def __iter__(self) :
+ return self.db.__iter__()
+
 
 def open(self, *args, **kwargs):
 self.db.open(*args, **kwargs)
Modified: python/trunk/Lib/bsddb/dbtables.py
==============================================================================
--- python/trunk/Lib/bsddb/dbtables.py	(original)
+++ python/trunk/Lib/bsddb/dbtables.py	Wed Jul 23 13:38:42 2008
@@ -22,7 +22,6 @@
 import copy
 import random
 import struct
-from types import ListType, StringType
 import cPickle as pickle
 
 try:
@@ -229,7 +228,7 @@
 
 raises TableDBError if it already exists or for other DB errors.
 """
- assert isinstance(columns, ListType)
+ assert isinstance(columns, list)
 txn = None
 try:
 # checking sanity of the table and column names here on
@@ -270,7 +269,7 @@
 """Return a list of columns in the given table.
 [] if the table doesn't exist.
 """
- assert isinstance(table, StringType)
+ assert isinstance(table, str)
 if contains_metastrings(table):
 raise ValueError, "bad table name: contains reserved metastrings"
 
@@ -300,7 +299,7 @@
 additional columns present in the given list as well as
 all of its current columns.
 """
- assert isinstance(columns, ListType)
+ assert isinstance(columns, list)
 try:
 self.CreateTable(table, columns)
 except TableAlreadyExists:
Modified: python/trunk/Lib/bsddb/dbutils.py
==============================================================================
--- python/trunk/Lib/bsddb/dbutils.py	(original)
+++ python/trunk/Lib/bsddb/dbutils.py	Wed Jul 23 13:38:42 2008
@@ -26,7 +26,13 @@
 #
 from time import sleep as _sleep
 
-import db
+import sys
+absolute_import = (sys.version_info[0] >= 3)
+if absolute_import :
+ # Because this syntaxis is not valid before Python 2.5
+ exec("from . import db")
+else :
+ import db
 
 # always sleep at least N seconds between retrys
 _deadlock_MinSleepTime = 1.0/128
Modified: python/trunk/Lib/bsddb/test/test_all.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_all.py	(original)
+++ python/trunk/Lib/bsddb/test/test_all.py	Wed Jul 23 13:38:42 2008
@@ -7,15 +7,24 @@
 try:
 # For Pythons w/distutils pybsddb
 from bsddb3 import db
+ import bsddb3 as bsddb
 except ImportError:
 # For Python 2.3
 from bsddb import db
+ import bsddb
 
 try:
 from bsddb3 import test_support
 except ImportError:
 from test import test_support
 
+try:
+ from threading import Thread, currentThread
+ del Thread, currentThread
+ have_threads = True
+except ImportError:
+ have_threads = False
+
 verbose = 0
 if 'verbose' in sys.argv:
 verbose = 1
@@ -33,6 +42,8 @@
 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__
 print 'python version: %s' % sys.version
 print 'My pid: %s' % os.getpid()
 print '-=' * 38
@@ -81,11 +92,11 @@
 def remove_test_path_directory() :
 test_support.rmtree(get_new_path.prefix)
 
-try :
+if have_threads :
 import threading
 get_new_path.mutex=threading.Lock()
 del threading
-except ImportError:
+else :
 class Lock(object) :
 def acquire(self) :
 pass
@@ -104,8 +115,12 @@
 # This little hack is for when this module is run as main and all the
 # other modules import it so they will still be able to get the right
 # verbose setting. It's confusing but it works.
-import test_all
-test_all.verbose = verbose
+if sys.version_info[0] < 3 :
+ import test_all
+ test_all.verbose = verbose
+else :
+ import sys
+ print >>sys.stderr, "Work to do!"
 
 
 def suite(module_prefix='', timing_check=None):
Modified: python/trunk/Lib/bsddb/test/test_associate.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_associate.py	(original)
+++ python/trunk/Lib/bsddb/test/test_associate.py	Wed Jul 23 13:38:42 2008
@@ -6,14 +6,8 @@
 import time
 from pprint import pprint
 
-try:
- from threading import Thread, currentThread
- have_threads = 1
-except ImportError:
- have_threads = 0
-
 import unittest
-from test_all import verbose, get_new_environment_path
+from test_all import verbose, have_threads, get_new_environment_path
 
 try:
 # For Pythons w/distutils pybsddb
@@ -435,24 +429,23 @@
 def test_suite():
 suite = unittest.TestSuite()
 
- if db.version() >= (3, 3, 11):
- suite.addTest(unittest.makeSuite(AssociateErrorTestCase))
-
- suite.addTest(unittest.makeSuite(AssociateHashTestCase))
- suite.addTest(unittest.makeSuite(AssociateBTreeTestCase))
- suite.addTest(unittest.makeSuite(AssociateRecnoTestCase))
-
- if db.version() >= (4, 1):
- suite.addTest(unittest.makeSuite(AssociateBTreeTxnTestCase))
+ suite.addTest(unittest.makeSuite(AssociateErrorTestCase))
 
- suite.addTest(unittest.makeSuite(ShelveAssociateHashTestCase))
- suite.addTest(unittest.makeSuite(ShelveAssociateBTreeTestCase))
- suite.addTest(unittest.makeSuite(ShelveAssociateRecnoTestCase))
-
- if have_threads:
- suite.addTest(unittest.makeSuite(ThreadedAssociateHashTestCase))
- suite.addTest(unittest.makeSuite(ThreadedAssociateBTreeTestCase))
- suite.addTest(unittest.makeSuite(ThreadedAssociateRecnoTestCase))
+ suite.addTest(unittest.makeSuite(AssociateHashTestCase))
+ suite.addTest(unittest.makeSuite(AssociateBTreeTestCase))
+ suite.addTest(unittest.makeSuite(AssociateRecnoTestCase))
+
+ if db.version() >= (4, 1):
+ suite.addTest(unittest.makeSuite(AssociateBTreeTxnTestCase))
+
+ suite.addTest(unittest.makeSuite(ShelveAssociateHashTestCase))
+ suite.addTest(unittest.makeSuite(ShelveAssociateBTreeTestCase))
+ suite.addTest(unittest.makeSuite(ShelveAssociateRecnoTestCase))
+
+ if have_threads:
+ suite.addTest(unittest.makeSuite(ThreadedAssociateHashTestCase))
+ suite.addTest(unittest.makeSuite(ThreadedAssociateBTreeTestCase))
+ suite.addTest(unittest.makeSuite(ThreadedAssociateRecnoTestCase))
 
 return suite
 
Modified: python/trunk/Lib/bsddb/test/test_basics.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_basics.py	(original)
+++ python/trunk/Lib/bsddb/test/test_basics.py	Wed Jul 23 13:38:42 2008
@@ -101,14 +101,14 @@
 def populateDB(self, _txn=None):
 d = self.d
 
- for x in range(self._numKeys/2):
+ for x in range(self._numKeys//2):
 key = '%04d' % (self._numKeys - x) # insert keys in reverse order
 data = self.makeData(key)
 d.put(key, data, _txn)
 
 d.put('empty value', '', _txn)
 
- for x in range(self._numKeys/2-1):
+ for x in range(self._numKeys//2-1):
 key = '%04d' % x # and now some in forward order
 data = self.makeData(key)
 d.put(key, data, _txn)
@@ -536,10 +536,6 @@
 #----------------------------------------
 
 def test06_Truncate(self):
- if db.version() < (3,3):
- # truncate is a feature of Berkeley DB 3.3 and above
- return
-
 d = self.d
 if verbose:
 print '\n', '-=' * 30
@@ -681,12 +677,11 @@
 except db.DBIncompleteError:
 pass
 
- if db.version() >= (4,0):
- statDict = self.env.log_stat(0);
- self.assert_(statDict.has_key('magic'))
- self.assert_(statDict.has_key('version'))
- self.assert_(statDict.has_key('cur_file'))
- self.assert_(statDict.has_key('region_nowait'))
+ statDict = self.env.log_stat(0);
+ self.assert_(statDict.has_key('magic'))
+ self.assert_(statDict.has_key('version'))
+ self.assert_(statDict.has_key('cur_file'))
+ self.assert_(statDict.has_key('region_nowait'))
 
 # must have at least one log file present:
 logs = self.env.log_archive(db.DB_ARCH_ABS | db.DB_ARCH_LOG)
@@ -703,10 +698,6 @@
 #----------------------------------------
 
 def test07_TxnTruncate(self):
- if db.version() < (3,3):
- # truncate is a feature of Berkeley DB 3.3 and above
- return
-
 d = self.d
 if verbose:
 print '\n', '-=' * 30
@@ -956,6 +947,55 @@
 envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
 
 
+class PrivateObject(unittest.TestCase) :
+ import sys
+ if sys.version_info[:3] < (2, 4, 0):
+ def assertTrue(self, expr, msg=None):
+ self.failUnless(expr,msg=msg)
+
+ def tearDown(self) :
+ del self.obj
+
+ def test01_DefaultIsNone(self) :
+ self.assertEqual(self.obj.get_private(), None)
+
+ def test02_assignment(self) :
+ a = "example of private object"
+ self.obj.set_private(a)
+ b = self.obj.get_private()
+ self.assertTrue(a is b) # Object identity
+
+ def test03_leak_assignment(self) :
+ import sys
+ a = "example of private object"
+ refcount = sys.getrefcount(a)
+ self.obj.set_private(a)
+ self.assertEqual(refcount+1, sys.getrefcount(a))
+ self.obj.set_private(None)
+ self.assertEqual(refcount, sys.getrefcount(a))
+
+ def test04_leak_GC(self) :
+ import sys
+ a = "example of private object"
+ refcount = sys.getrefcount(a)
+ self.obj.set_private(a)
+ self.obj = None
+ self.assertEqual(refcount, sys.getrefcount(a))
+
+class DBEnvPrivateObject(PrivateObject) :
+ def setUp(self) :
+ self.obj = db.DBEnv()
+
+class DBPrivateObject(PrivateObject) :
+ def setUp(self) :
+ self.obj = db.DB()
+
+class CrashAndBurn(unittest.TestCase) :
+ def test01_OpenCrash(self) :
+ # See http://bugs.python.org/issue3307
+ self.assertRaises(db.DBInvalidArgError, db.DB, None, 65535)
+
+
 #----------------------------------------------------------------------
 #----------------------------------------------------------------------
 
@@ -979,6 +1019,9 @@
 suite.addTest(unittest.makeSuite(HashDUPWithThreadTestCase))
 suite.addTest(unittest.makeSuite(BTreeMultiDBTestCase))
 suite.addTest(unittest.makeSuite(HashMultiDBTestCase))
+ suite.addTest(unittest.makeSuite(DBEnvPrivateObject))
+ suite.addTest(unittest.makeSuite(DBPrivateObject))
+ #suite.addTest(unittest.makeSuite(CrashAndBurn))
 
 return suite
 
Modified: python/trunk/Lib/bsddb/test/test_compare.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_compare.py	(original)
+++ python/trunk/Lib/bsddb/test/test_compare.py	Wed Jul 23 13:38:42 2008
@@ -240,9 +240,8 @@
 res = unittest.TestSuite ()
 
 res.addTest (unittest.makeSuite (ComparatorTests))
- if db.version () >= (3, 3, 11):
- res.addTest (unittest.makeSuite (BtreeExceptionsTestCase))
- res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase))
+ res.addTest (unittest.makeSuite (BtreeExceptionsTestCase))
+ res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase))
 return res
 
 if __name__ == '__main__':
Modified: python/trunk/Lib/bsddb/test/test_lock.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_lock.py	(original)
+++ python/trunk/Lib/bsddb/test/test_lock.py	Wed Jul 23 13:38:42 2008
@@ -4,15 +4,11 @@
 
 import time
 
-try:
- from threading import Thread, currentThread
- have_threads = 1
-except ImportError:
- have_threads = 0
-
-
 import unittest
-from test_all import verbose, get_new_environment_path, get_new_database_path
+from test_all import verbose, have_threads, get_new_environment_path, get_new_database_path
+
+if have_threads :
+ from threading import Thread, currentThread
 
 try:
 # For Pythons w/distutils pybsddb
@@ -62,8 +58,7 @@
 self.env.lock_put(lock)
 if verbose:
 print "Released lock: %s" % lock
- if db.version() >= (4,0):
- self.env.lock_id_free(anID)
+ self.env.lock_id_free(anID)
 
 
 def test02_threaded(self):
@@ -132,9 +127,8 @@
 self.env.lock_put(lock)
 t.join()
 
- if db.version() >= (4,0):
- self.env.lock_id_free(anID)
- self.env.lock_id_free(anID2)
+ self.env.lock_id_free(anID)
+ self.env.lock_id_free(anID2)
 
 if db.version() >= (4,6):
 self.assertTrue(deadlock_detection.count>0)
@@ -159,8 +153,7 @@
 if verbose:
 print "%s: Released %s lock: %s" % (name, lt, lock)
 
- if db.version() >= (4,0):
- self.env.lock_id_free(anID)
+ self.env.lock_id_free(anID)
 
 
 #----------------------------------------------------------------------
Modified: python/trunk/Lib/bsddb/test/test_misc.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_misc.py	(original)
+++ python/trunk/Lib/bsddb/test/test_misc.py	Wed Jul 23 13:38:42 2008
@@ -47,6 +47,18 @@
 rp = repr(db)
 self.assertEquals(rp, "{}")
 
+ def test04_repr_db(self) :
+ db = hashopen(self.filename)
+ d = {}
+ for i in xrange(100) :
+ db[repr(i)] = repr(100*i)
+ d[repr(i)] = repr(100*i)
+ db.close()
+ db = hashopen(self.filename)
+ rp = repr(db)
+ self.assertEquals(rp, repr(d))
+ db.close()
+
 # http://sourceforge.net/tracker/index.php?func=detail&aid=1708868&group_id=13900&atid=313900
 #
 # See the bug report for details.
@@ -54,7 +66,7 @@
 # The problem was that make_key_dbt() was not allocating a copy of
 # string keys but FREE_DBT() was always being told to free it when the
 # database was opened with DB_THREAD.
- def test04_double_free_make_key_dbt(self):
+ def test05_double_free_make_key_dbt(self):
 try:
 db1 = db.DB()
 db1.open(self.filename, None, db.DB_BTREE,
@@ -67,7 +79,7 @@
 db1.close()
 os.unlink(self.filename)
 
- def test05_key_with_null_bytes(self):
+ def test06_key_with_null_bytes(self):
 try:
 db1 = db.DB()
 db1.open(self.filename, None, db.DB_HASH, db.DB_CREATE)
@@ -86,7 +98,7 @@
 db1.close()
 os.unlink(self.filename)
 
- def test_DB_set_flags_persists(self):
+ def test07_DB_set_flags_persists(self):
 if db.version() < (4,2):
 # The get_flags API required for this to work is only available
 # in Berkeley DB >= 4.2
Modified: python/trunk/Lib/bsddb/test/test_replication.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_replication.py	(original)
+++ python/trunk/Lib/bsddb/test/test_replication.py	Wed Jul 23 13:38:42 2008
@@ -12,7 +12,7 @@
 # For Python 2.3
 from bsddb import db
 
-from test_all import get_new_environment_path, get_new_database_path
+from test_all import have_threads, get_new_environment_path, get_new_database_path
 
 try:
 from bsddb3 import test_support
@@ -58,6 +58,25 @@
 self.dbenvMaster.set_event_notify(confirmed_master)
 self.dbenvClient.set_event_notify(client_startupdone)
 
+ #self.dbenvMaster.set_verbose(db.DB_VERB_REPLICATION, True)
+ #self.dbenvMaster.set_verbose(db.DB_VERB_FILEOPS_ALL, True)
+ #self.dbenvClient.set_verbose(db.DB_VERB_REPLICATION, True)
+ #self.dbenvClient.set_verbose(db.DB_VERB_FILEOPS_ALL, True)
+
+ self.dbMaster = self.dbClient = None
+
+
+ def tearDown(self):
+ if self.dbClient :
+ self.dbClient.close()
+ if self.dbMaster :
+ self.dbMaster.close()
+ self.dbenvClient.close()
+ self.dbenvMaster.close()
+ test_support.rmtree(self.homeDirClient)
+ test_support.rmtree(self.homeDirMaster)
+
+ def test01_basic_replication(self) :
 master_port = test_support.find_unused_port()
 self.dbenvMaster.repmgr_set_local_site("127.0.0.1", master_port)
 client_port = test_support.find_unused_port()
@@ -69,6 +88,27 @@
 self.dbenvMaster.rep_set_priority(10)
 self.dbenvClient.rep_set_priority(0)
 
+ self.dbenvMaster.rep_set_timeout(db.DB_REP_CONNECTION_RETRY,100123)
+ self.dbenvClient.rep_set_timeout(db.DB_REP_CONNECTION_RETRY,100321)
+ self.assertEquals(self.dbenvMaster.rep_get_timeout(
+ db.DB_REP_CONNECTION_RETRY), 100123)
+ self.assertEquals(self.dbenvClient.rep_get_timeout(
+ db.DB_REP_CONNECTION_RETRY), 100321)
+
+ self.dbenvMaster.rep_set_timeout(db.DB_REP_ELECTION_TIMEOUT, 100234)
+ self.dbenvClient.rep_set_timeout(db.DB_REP_ELECTION_TIMEOUT, 100432)
+ self.assertEquals(self.dbenvMaster.rep_get_timeout(
+ db.DB_REP_ELECTION_TIMEOUT), 100234)
+ self.assertEquals(self.dbenvClient.rep_get_timeout(
+ db.DB_REP_ELECTION_TIMEOUT), 100432)
+
+ self.dbenvMaster.rep_set_timeout(db.DB_REP_ELECTION_RETRY, 100345)
+ self.dbenvClient.rep_set_timeout(db.DB_REP_ELECTION_RETRY, 100543)
+ self.assertEquals(self.dbenvMaster.rep_get_timeout(
+ db.DB_REP_ELECTION_RETRY), 100345)
+ self.assertEquals(self.dbenvClient.rep_get_timeout(
+ db.DB_REP_ELECTION_RETRY), 100543)
+
 self.dbenvMaster.repmgr_set_ack_policy(db.DB_REPMGR_ACKS_ALL)
 self.dbenvClient.repmgr_set_ack_policy(db.DB_REPMGR_ACKS_ALL)
 
@@ -84,23 +124,14 @@
 self.assertEquals(self.dbenvClient.repmgr_get_ack_policy(),
 db.DB_REPMGR_ACKS_ALL)
 
- #self.dbenvMaster.set_verbose(db.DB_VERB_REPLICATION, True)
- #self.dbenvMaster.set_verbose(db.DB_VERB_FILEOPS_ALL, True)
- #self.dbenvClient.set_verbose(db.DB_VERB_REPLICATION, True)
- #self.dbenvClient.set_verbose(db.DB_VERB_FILEOPS_ALL, True)
-
- self.dbMaster = self.dbClient = None
-
 # The timeout is necessary in BDB 4.5, since DB_EVENT_REP_STARTUPDONE
 # is not generated if the master has no new transactions.
 # This is solved in BDB 4.6 (#15542).
- timeout = time.time()+10
+ import time
+ timeout = time.time()+2
 while (time.time()<timeout) and not (self.confirmed_master and self.client_startupdone) :
 time.sleep(0.02)
- if db.version() >= (4,6) :
- self.assertTrue(time.time()<timeout)
- else :
- self.assertTrue(time.time()>=timeout)
+ self.assertTrue(time.time()<timeout)
 
 d = self.dbenvMaster.repmgr_site_list()
 self.assertEquals(len(d), 1)
@@ -120,17 +151,158 @@
 d = self.dbenvMaster.repmgr_stat(flags=db.DB_STAT_CLEAR);
 self.assertTrue("msgs_queued" in d)
 
+ self.dbMaster=db.DB(self.dbenvMaster)
+ txn=self.dbenvMaster.txn_begin()
+ self.dbMaster.open("test", db.DB_HASH, db.DB_CREATE, 0666, txn=txn)
+ txn.commit()
+
+ import time,os.path
+ timeout=time.time()+10
+ while (time.time()<timeout) and \
+ not (os.path.exists(os.path.join(self.homeDirClient,"test"))) :
+ time.sleep(0.01)
+
+ self.dbClient=db.DB(self.dbenvClient)
+ while True :
+ txn=self.dbenvClient.txn_begin()
+ try :
+ self.dbClient.open("test", db.DB_HASH, flags=db.DB_RDONLY,
+ mode=0666, txn=txn)
+ except db.DBRepHandleDeadError :
+ txn.abort()
+ self.dbClient.close()
+ self.dbClient=db.DB(self.dbenvClient)
+ continue
+
+ txn.commit()
+ break
+
+ txn=self.dbenvMaster.txn_begin()
+ self.dbMaster.put("ABC", "123", txn=txn)
+ txn.commit()
+ import time
+ timeout=time.time()+1
+ v=None
+ while (time.time()<timeout) and (v==None) :
+ txn=self.dbenvClient.txn_begin()
+ v=self.dbClient.get("ABC", txn=txn)
+ txn.commit()
+ self.assertEquals("123", v)
+
+ txn=self.dbenvMaster.txn_begin()
+ self.dbMaster.delete("ABC", txn=txn)
+ txn.commit()
+ timeout=time.time()+1
+ while (time.time()<timeout) and (v!=None) :
+ txn=self.dbenvClient.txn_begin()
+ v=self.dbClient.get("ABC", txn=txn)
+ txn.commit()
+ self.assertEquals(None, v)
+
+class DBBaseReplication(DBReplicationManager):
+ def setUp(self) :
+ DBReplicationManager.setUp(self)
+ def confirmed_master(a,b,c) :
+ if (b == db.DB_EVENT_REP_MASTER) or (b == db.DB_EVENT_REP_ELECTED) :
+ self.confirmed_master = True
+
+ def client_startupdone(a,b,c) :
+ if b == db.DB_EVENT_REP_STARTUPDONE :
+ self.client_startupdone = True
+
+ self.dbenvMaster.set_event_notify(confirmed_master)
+ self.dbenvClient.set_event_notify(client_startupdone)
+
+ import Queue
+ self.m2c = Queue.Queue()
+ self.c2m = Queue.Queue()
+
+ # There are only two nodes, so we don't need to
+ # do any routing decision
+ def m2c(dbenv, control, rec, lsnp, envid, flags) :
+ self.m2c.put((control, rec))
+
+ def c2m(dbenv, control, rec, lsnp, envid, flags) :
+ self.c2m.put((control, rec))
+
+ self.dbenvMaster.rep_set_transport(13,m2c)
+ self.dbenvMaster.rep_set_priority(10)
+ self.dbenvClient.rep_set_transport(3,c2m)
+ self.dbenvClient.rep_set_priority(0)
+
+ self.assertEquals(self.dbenvMaster.rep_get_priority(),10)
+ self.assertEquals(self.dbenvClient.rep_get_priority(),0)
+
+ #self.dbenvMaster.set_verbose(db.DB_VERB_REPLICATION, True)
+ #self.dbenvMaster.set_verbose(db.DB_VERB_FILEOPS_ALL, True)
+ #self.dbenvClient.set_verbose(db.DB_VERB_REPLICATION, True)
+ #self.dbenvClient.set_verbose(db.DB_VERB_FILEOPS_ALL, True)
+
+ def thread_master() :
+ return self.thread_do(self.dbenvMaster, self.c2m, 3,
+ self.master_doing_election, True)
+
+ def thread_client() :
+ return self.thread_do(self.dbenvClient, self.m2c, 13,
+ self.client_doing_election, False)
+
+ from threading import Thread
+ t_m=Thread(target=thread_master)
+ t_m.setDaemon(True)
+ t_c=Thread(target=thread_client)
+ t_c.setDaemon(True)
+
+ self.t_m = t_m
+ self.t_c = t_c
+
+ self.dbMaster = self.dbClient = None
+
+ self.master_doing_election=[False]
+ self.client_doing_election=[False]
+
+
 def tearDown(self):
 if self.dbClient :
 self.dbClient.close()
 if self.dbMaster :
 self.dbMaster.close()
+ self.m2c.put(None)
+ self.c2m.put(None)
+ self.t_m.join()
+ self.t_c.join()
 self.dbenvClient.close()
 self.dbenvMaster.close()
 test_support.rmtree(self.homeDirClient)
 test_support.rmtree(self.homeDirMaster)
 
+ def basic_rep_threading(self) :
+ self.dbenvMaster.rep_start(flags=db.DB_REP_MASTER)
+ self.dbenvClient.rep_start(flags=db.DB_REP_CLIENT)
+
+ def thread_do(env, q, envid, election_status, must_be_master) :
+ while True :
+ v=q.get()
+ if v == None : return
+ env.rep_process_message(v[0], v[1], envid)
+
+ self.thread_do = thread_do
+
+ self.t_m.start()
+ self.t_c.start()
+
 def test01_basic_replication(self) :
+ self.basic_rep_threading()
+
+ # The timeout is necessary in BDB 4.5, since DB_EVENT_REP_STARTUPDONE
+ # is not generated if the master has no new transactions.
+ # This is solved in BDB 4.6 (#15542).
+ import time
+ timeout = time.time()+2
+ while (time.time()<timeout) and not (self.confirmed_master and
+ self.client_startupdone) :
+ time.sleep(0.02)
+ self.assertTrue(time.time()<timeout)
+
 self.dbMaster=db.DB(self.dbenvMaster)
 txn=self.dbenvMaster.txn_begin()
 self.dbMaster.open("test", db.DB_HASH, db.DB_CREATE, 0666, txn=txn)
@@ -179,11 +351,69 @@
 txn.commit()
 self.assertEquals(None, v)
 
+ if db.version() >= (4,7) :
+ def test02_test_request(self) :
+ self.basic_rep_threading()
+ (minimum, maximum) = self.dbenvClient.rep_get_request()
+ self.dbenvClient.rep_set_request(minimum-1, maximum+1)
+ self.assertEqual(self.dbenvClient.rep_get_request(),
+ (minimum-1, maximum+1))
+
+ if db.version() >= (4,6) :
+ def test03_master_election(self) :
+ # Get ready to hold an election
+ #self.dbenvMaster.rep_start(flags=db.DB_REP_MASTER)
+ self.dbenvMaster.rep_start(flags=db.DB_REP_CLIENT)
+ self.dbenvClient.rep_start(flags=db.DB_REP_CLIENT)
+
+ def thread_do(env, q, envid, election_status, must_be_master) :
+ while True :
+ v=q.get()
+ if v == None : return
+ r = env.rep_process_message(v[0],v[1],envid)
+ if must_be_master and self.confirmed_master :
+ self.dbenvMaster.rep_start(flags = db.DB_REP_MASTER)
+ must_be_master = False
+
+ if r[0] == db.DB_REP_HOLDELECTION :
+ def elect() :
+ while True :
+ try :
+ env.rep_elect(2, 1)
+ election_status[0] = False
+ break
+ except db.DBRepUnavailError :
+ pass
+ if not election_status[0] and not self.confirmed_master :
+ from threading import Thread
+ election_status[0] = True
+ t=Thread(target=elect)
+ t.setDaemon(True)
+ t.start()
+
+ self.thread_do = thread_do
+
+ self.t_m.start()
+ self.t_c.start()
+
+ self.dbenvMaster.rep_set_timeout(db.DB_REP_ELECTION_TIMEOUT, 50000)
+ self.dbenvClient.rep_set_timeout(db.DB_REP_ELECTION_TIMEOUT, 50000)
+ self.client_doing_election[0] = True
+ while True :
+ try :
+ self.dbenvClient.rep_elect(2, 1)
+ self.client_doing_election[0] = False
+ break
+ except db.DBRepUnavailError :
+ pass
+
+ self.assertTrue(self.confirmed_master)
+
 #----------------------------------------------------------------------
 
 def test_suite():
 suite = unittest.TestSuite()
- if db.version() >= (4,5) :
+ if db.version() >= (4, 6) :
 dbenv = db.DBEnv()
 try :
 dbenv.repmgr_get_ack_policy()
@@ -194,6 +424,10 @@
 del dbenv
 if ReplicationManager_available :
 suite.addTest(unittest.makeSuite(DBReplicationManager))
+
+ if have_threads :
+ suite.addTest(unittest.makeSuite(DBBaseReplication))
+
 return suite
 
 
Modified: python/trunk/Lib/bsddb/test/test_thread.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_thread.py	(original)
+++ python/trunk/Lib/bsddb/test/test_thread.py	Wed Jul 23 13:38:42 2008
@@ -7,28 +7,19 @@
 import errno
 from random import random
 
-try:
- True, False
-except NameError:
- True = 1
- False = 0
-
 DASH = '-'
 
 try:
- from threading import Thread, currentThread
- have_threads = True
-except ImportError:
- have_threads = False
-
-try:
 WindowsError
 except NameError:
 class WindowsError(Exception):
 pass
 
 import unittest
-from test_all import verbose, get_new_environment_path, get_new_database_path
+from test_all import verbose, have_threads, get_new_environment_path, get_new_database_path
+
+if have_threads :
+ from threading import Thread, currentThread
 
 
 try:
@@ -103,8 +94,8 @@
 keys=range(self.records)
 import random
 random.shuffle(keys)
- records_per_writer=self.records/self.writers
- readers_per_writer=self.readers/self.writers
+ records_per_writer=self.records//self.writers
+ readers_per_writer=self.readers//self.writers
 self.assertEqual(self.records,self.writers*records_per_writer)
 self.assertEqual(self.readers,self.writers*readers_per_writer)
 self.assertTrue((records_per_writer%readers_per_writer)==0)
@@ -143,7 +134,7 @@
 if verbose:
 print "%s: creating records %d - %d" % (name, start, stop)
 
- count=len(keys)/len(readers)
+ count=len(keys)//len(readers)
 count2=count
 for x in keys :
 key = '%04d' % x
@@ -218,8 +209,8 @@
 keys=range(self.records)
 import random
 random.shuffle(keys)
- records_per_writer=self.records/self.writers
- readers_per_writer=self.readers/self.writers
+ records_per_writer=self.records//self.writers
+ readers_per_writer=self.readers//self.writers
 self.assertEqual(self.records,self.writers*records_per_writer)
 self.assertEqual(self.readers,self.writers*readers_per_writer)
 self.assertTrue((records_per_writer%readers_per_writer)==0)
@@ -258,7 +249,7 @@
 if verbose:
 print "%s: creating records %d - %d" % (name, start, stop)
 
- count=len(keys)/len(readers)
+ count=len(keys)//len(readers)
 count2=count
 for x in keys :
 key = '%04d' % x
@@ -332,8 +323,8 @@
 keys=range(self.records)
 import random
 random.shuffle(keys)
- records_per_writer=self.records/self.writers
- readers_per_writer=self.readers/self.writers
+ records_per_writer=self.records//self.writers
+ readers_per_writer=self.readers//self.writers
 self.assertEqual(self.records,self.writers*records_per_writer)
 self.assertEqual(self.readers,self.writers*readers_per_writer)
 self.assertTrue((records_per_writer%readers_per_writer)==0)
@@ -375,7 +366,7 @@
 
 def writerThread(self, d, keys, readers):
 name = currentThread().getName()
- count=len(keys)/len(readers)
+ count=len(keys)//len(readers)
 while len(keys):
 try:
 txn = self.env.txn_begin(None, self.txnFlag)
Modified: python/trunk/Modules/_bsddb.c
==============================================================================
--- python/trunk/Modules/_bsddb.c	(original)
+++ python/trunk/Modules/_bsddb.c	Wed Jul 23 13:38:42 2008
@@ -115,6 +115,16 @@
 #define PyBytes_AS_STRING PyString_AS_STRING
 #endif
 
+#if (PY_VERSION_HEX >= 0x03000000)
+#define NUMBER_Check PyLong_Check
+#define NUMBER_AsLong PyLong_AsLong
+#define NUMBER_FromLong PyLong_FromLong
+#else
+#define NUMBER_Check PyInt_Check
+#define NUMBER_AsLong PyInt_AsLong
+#define NUMBER_FromLong PyInt_FromLong
+#endif
+
 #ifdef WITH_THREAD
 
 /* These are for when calling Python --> C */
@@ -178,10 +188,8 @@
 static PyObject* DBNoServerError; /* DB_NOSERVER */
 static PyObject* DBNoServerHomeError; /* DB_NOSERVER_HOME */
 static PyObject* DBNoServerIDError; /* DB_NOSERVER_ID */
-#if (DBVER >= 33)
 static PyObject* DBPageNotFoundError; /* DB_PAGE_NOTFOUND */
 static PyObject* DBSecondaryBadError; /* DB_SECONDARY_BAD */
-#endif
 
 #if !INCOMPLETE_IS_WARNING
 static PyObject* DBIncompleteError; /* DB_INCOMPLETE */
@@ -201,6 +209,8 @@
 static PyObject* DBRepHandleDeadError; /* DB_REP_HANDLE_DEAD */
 #endif
 
+static PyObject* DBRepUnavailError; /* DB_REP_UNAVAIL */
+
 #if (DBVER < 43)
 #define	DB_BUFFER_SMALL		ENOMEM
 #endif
@@ -219,7 +229,16 @@
 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
 
 
-staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
+/* See comment in Python 2.6 "object.h" */
+#ifndef staticforward
+#define staticforward static
+#endif
+#ifndef statichere
+#define statichere static
+#endif
+
+staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type,
+ DBLock_Type;
 #if (DBVER >= 43)
 staticforward PyTypeObject DBSequence_Type;
 #endif
@@ -320,8 +339,10 @@
 if ((nonNull) == NULL) { \
 PyObject *errTuple = NULL; \
 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
- PyErr_SetObject((pyErrObj), errTuple); \
-	Py_DECREF(errTuple); \
+ if (errTuple) { \
+ PyErr_SetObject((pyErrObj), errTuple); \
+ Py_DECREF(errTuple); \
+ } \
 return NULL; \
 }
 
@@ -354,17 +375,14 @@
 /* Return the access method type of the DBObject */
 static int _DB_get_type(DBObject* self)
 {
-#if (DBVER >= 33)
 DBTYPE type;
 int err;
+
 err = self->db->get_type(self->db, &type);
 if (makeDBError(err)) {
 return -1;
 }
 return type;
-#else
- return self->db->get_type(self->db);
-#endif
 }
 
 
@@ -439,7 +457,7 @@
 key->size = PyBytes_GET_SIZE(keyobj);
 }
 
- else if (PyInt_Check(keyobj)) {
+ else if (NUMBER_Check(keyobj)) {
 /* verify access method type */
 type = _DB_get_type(self);
 if (type == -1)
@@ -458,7 +476,7 @@
 
 /* Make a key out of the requested recno, use allocated space so DB
 * will be able to realloc room for the real key if needed. */
- recno = PyInt_AS_LONG(keyobj);
+ recno = NUMBER_AsLong(keyobj);
 key->data = malloc(sizeof(db_recno_t));
 if (key->data == NULL) {
 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
@@ -634,10 +652,8 @@
 case DB_NOSERVER: errObj = DBNoServerError; break;
 case DB_NOSERVER_HOME: errObj = DBNoServerHomeError; break;
 case DB_NOSERVER_ID: errObj = DBNoServerIDError; break;
-#if (DBVER >= 33)
 case DB_PAGE_NOTFOUND: errObj = DBPageNotFoundError; break;
 case DB_SECONDARY_BAD: errObj = DBSecondaryBadError; break;
-#endif
 case DB_BUFFER_SMALL: errObj = DBNoMemoryError; break;
 
 #if (DBVER >= 43)
@@ -657,6 +673,8 @@
 case DB_REP_HANDLE_DEAD : errObj = DBRepHandleDeadError; break;
 #endif
 
+ case DB_REP_UNAVAIL : errObj = DBRepUnavailError; break;
+
 default: errObj = DBError; break;
 }
 
@@ -671,9 +689,13 @@
 }
 _db_errmsg[0] = 0;
 
-	errTuple = Py_BuildValue("(is)", err, errTxt);
+ errTuple = Py_BuildValue("(is)", err, errTxt);
+ if (errTuple == NULL) {
+ Py_DECREF(errObj);
+ return !0;
+ }
 PyErr_SetObject(errObj, errTuple);
-	Py_DECREF(errTuple);
+ Py_DECREF(errTuple);
 }
 
 return ((errObj != NULL) || exceptionRaised);
@@ -801,7 +823,7 @@
 /* add an integer to a dictionary using the given name as a key */
 static void _addIntToDict(PyObject* dict, char *name, int value)
 {
- PyObject* v = PyInt_FromLong((long) value);
+ PyObject* v = NUMBER_FromLong((long) value);
 if (!v || PyDict_SetItemString(dict, name, v))
 PyErr_Clear();
 
@@ -818,7 +840,7 @@
 		v = PyLong_FromLongLong((PY_LONG_LONG) value);
 	else
 #endif
-		v = PyInt_FromLong((long) value);
+		v = NUMBER_FromLong((long) value);
 if (!v || PyDict_SetItemString(dict, name, v))
 PyErr_Clear();
 
@@ -837,7 +859,6 @@
 }
 #endif
 
-#if (DBVER >= 40)
 static void _addDB_lsnToDict(PyObject* dict, char *name, DB_LSN value)
 {
 PyObject *v = Py_BuildValue("(ll)",value.file,value.offset);
@@ -846,7 +867,6 @@
 
 Py_XDECREF(v);
 }
-#endif
 
 /* --------------------------------------------------------------------- */
 /* Allocators and deallocators */
@@ -866,15 +886,16 @@
 self->flags = 0;
 self->setflags = 0;
 self->myenvobj = NULL;
+ self->db = NULL;
 self->children_cursors = NULL;
 #if (DBVER >=43)
 self->children_sequences = NULL;
 #endif
-#if (DBVER >= 33)
 self->associateCallback = NULL;
 self->btCompareCallback = NULL;
 self->primaryDBType = 0;
-#endif
+ Py_INCREF(Py_None);
+ self->private = Py_None;
 self->in_weakreflist = NULL;
 
 /* keep a reference to our python DBEnv object */
@@ -901,9 +922,7 @@
 err = db_create(&self->db, db_env, flags);
 if (self->db != NULL) {
 self->db->set_errcall(self->db, _db_errorCallback);
-#if (DBVER >= 33)
 self->db->app_private = (void*)self;
-#endif
 }
 MYDB_END_ALLOW_THREADS;
 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
@@ -940,7 +959,6 @@
 Py_DECREF(self->myenvobj);
 self->myenvobj = NULL;
 }
-#if (DBVER >= 33)
 if (self->associateCallback != NULL) {
 Py_DECREF(self->associateCallback);
 self->associateCallback = NULL;
@@ -949,7 +967,7 @@
 Py_DECREF(self->btCompareCallback);
 self->btCompareCallback = NULL;
 }
-#endif
+ Py_DECREF(self->private);
 PyObject_Del(self);
 }
 
@@ -1011,11 +1029,12 @@
 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
 self->children_dbs = NULL;
 self->children_txns = NULL;
+ Py_INCREF(Py_None);
+ self->private = Py_None;
+ Py_INCREF(Py_None);
+ self->rep_transport = Py_None;
 self->in_weakreflist = NULL;
-
-#if (DBVER >= 40)
 self->event_notifyCallback = NULL;
-#endif
 
 MYDB_BEGIN_ALLOW_THREADS;
 err = db_env_create(&self->db_env, flags);
@@ -1044,15 +1063,14 @@
 Py_XDECREF(dummy);
 }
 
-#if (DBVER >= 40)
 Py_XDECREF(self->event_notifyCallback);
 self->event_notifyCallback = NULL;
-#endif
 
 if (self->in_weakreflist != NULL) {
 PyObject_ClearWeakRefs((PyObject *) self);
 }
-
+ Py_DECREF(self->private);
+ Py_DECREF(self->rep_transport);
 PyObject_Del(self);
 }
 
@@ -1084,11 +1102,7 @@
 self->txn = txn;
 } else {
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = myenv->db_env->txn_begin(myenv->db_env, parent_txn, &(self->txn), flags);
-#else
- err = txn_begin(myenv->db_env, parent->txn, &(self_txn), flags);
-#endif
 MYDB_END_ALLOW_THREADS;
 
 if (makeDBError(err)) {
@@ -1156,12 +1170,8 @@
 self->in_weakreflist = NULL;
 
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
 &self->lock);
-#else
- err = lock_get(myenv->db_env, locker, flags, obj, lock_mode, &self->lock);
-#endif
 MYDB_END_ALLOW_THREADS;
 if (makeDBError(err)) {
 Py_DECREF(self);
@@ -1265,12 +1275,10 @@
 if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
 return NULL;
 
- return PyInt_FromLong(recno);
+ return NUMBER_FromLong(recno);
 }
 
 
-#if (DBVER >= 33)
-
 static int
 _db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
 DBT* secKey)
@@ -1299,8 +1307,8 @@
 else if (result == Py_None) {
 retval = DB_DONOTINDEX;
 }
- else if (PyInt_Check(result)) {
- retval = PyInt_AsLong(result);
+ else if (NUMBER_Check(result)) {
+ retval = NUMBER_AsLong(result);
 }
 else if (PyBytes_Check(result)) {
 char* data;
@@ -1426,9 +1434,6 @@
 }
 
 
-#endif
-
-
 static PyObject*
 DB_close_internal(DBObject* self, int flags)
 {
@@ -1598,19 +1603,17 @@
 
 
 static PyObject*
-DB_fd(DBObject* self, PyObject* args)
+DB_fd(DBObject* self)
 {
 int err, the_fd;
 
- if (!PyArg_ParseTuple(args,":fd"))
- return NULL;
 CHECK_DB_NOT_CLOSED(self);
 
 MYDB_BEGIN_ALLOW_THREADS;
 err = self->db->fd(self->db, &the_fd);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(the_fd);
+ return NUMBER_FromLong(the_fd);
 }
 
 
@@ -1680,7 +1683,6 @@
 return retval;
 }
 
-#if (DBVER >= 33)
 static PyObject*
 DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
 {
@@ -1721,7 +1723,7 @@
 
 CLEAR_DBT(pkey);
 pkey.flags = DB_DBT_MALLOC;
- 
+
 MYDB_BEGIN_ALLOW_THREADS;
 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
 MYDB_END_ALLOW_THREADS;
@@ -1744,7 +1746,7 @@
 
 if (self->primaryDBType == DB_RECNO ||
 self->primaryDBType == DB_QUEUE)
- pkeyObj = PyInt_FromLong(*(int *)pkey.data);
+ pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
 else
 pkeyObj = Build_PyString(pkey.data, pkey.size);
 
@@ -1753,7 +1755,7 @@
 PyObject *keyObj;
 int type = _DB_get_type(self);
 if (type == DB_RECNO || type == DB_QUEUE)
- keyObj = PyInt_FromLong(*(int *)key.data);
+ keyObj = NUMBER_FromLong(*(int *)key.data);
 else
 keyObj = Build_PyString(key.data, key.size);
 #if (PY_VERSION_HEX >= 0x02040000)
@@ -1773,7 +1775,7 @@
 }
 Py_DECREF(dataObj);
 Py_DECREF(pkeyObj);
-	FREE_DBT(pkey);
+ FREE_DBT(pkey);
 FREE_DBT(data);
 }
 FREE_DBT(key);
@@ -1781,7 +1783,6 @@
 RETURN_IF_ERR();
 return retval;
 }
-#endif
 
 
 /* Return size of entry */
@@ -1816,7 +1817,7 @@
 err = self->db->get(self->db, txn, &key, &data, flags);
 MYDB_END_ALLOW_THREADS;
 if (err == DB_BUFFER_SMALL) {
- retval = PyInt_FromLong((long)data.size);
+ retval = NUMBER_FromLong((long)data.size);
 err = 0;
 }
 
@@ -1840,7 +1841,6 @@
 DB_TXN *txn = NULL;
 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
 
-
 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
 &keyobj, &dataobj, &txnobj, &flags))
 return NULL;
@@ -1891,44 +1891,32 @@
 
 
 static PyObject*
-DB_get_byteswapped(DBObject* self, PyObject* args)
+DB_get_byteswapped(DBObject* self)
 {
-#if (DBVER >= 33)
 int err = 0;
-#endif
 int retval = -1;
 
- if (!PyArg_ParseTuple(args,":get_byteswapped"))
- return NULL;
 CHECK_DB_NOT_CLOSED(self);
 
-#if (DBVER >= 33)
 MYDB_BEGIN_ALLOW_THREADS;
 err = self->db->get_byteswapped(self->db, &retval);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
-#else
- MYDB_BEGIN_ALLOW_THREADS;
- retval = self->db->get_byteswapped(self->db);
- MYDB_END_ALLOW_THREADS;
-#endif
- return PyInt_FromLong(retval);
+ return NUMBER_FromLong(retval);
 }
 
 
 static PyObject*
-DB_get_type(DBObject* self, PyObject* args)
+DB_get_type(DBObject* self)
 {
 int type;
 
- if (!PyArg_ParseTuple(args,":get_type"))
- return NULL;
 CHECK_DB_NOT_CLOSED(self);
 
 type = _DB_get_type(self);
 if (type == -1)
 return NULL;
- return PyInt_FromLong(type);
+ return NUMBER_FromLong(type);
 }
 
 
@@ -2079,8 +2067,10 @@
 if (NULL == self->db) {
 PyObject *t = Py_BuildValue("(is)", 0,
 "Cannot call open() twice for DB object");
- PyErr_SetObject(DBError, t);
- Py_DECREF(t);
+ if (t) {
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ }
 return NULL;
 }
 
@@ -2154,7 +2144,7 @@
 }
 
 if (flags & DB_APPEND)
- retval = PyInt_FromLong(*((db_recno_t*)key.data));
+ retval = NUMBER_FromLong(*((db_recno_t*)key.data));
 else {
 retval = Py_None;
 Py_INCREF(retval);
@@ -2208,6 +2198,25 @@
 
 
 static PyObject*
+DB_get_private(DBObject* self)
+{
+ /* We can give out the private field even if db is closed */
+ Py_INCREF(self->private);
+ return self->private;
+}
+
+static PyObject*
+DB_set_private(DBObject* self, PyObject* private)
+{
+ /* We can set the private field even if db is closed */
+ Py_DECREF(self->private);
+ Py_INCREF(private);
+ self->private = private;
+ RETURN_NONE();
+}
+
+
+static PyObject*
 DB_set_bt_minkey(DBObject* self, PyObject* args)
 {
 int err, minkey;
@@ -2223,17 +2232,16 @@
 RETURN_NONE();
 }
 
-#if (DBVER >= 33)
-static int 
+static int
 _default_cmp(const DBT *leftKey,
 	 const DBT *rightKey)
 {
 int res;
 int lsize = leftKey->size, rsize = rightKey->size;
 
- res = memcmp(leftKey->data, rightKey->data, 
+ res = memcmp(leftKey->data, rightKey->data,
 	 lsize < rsize ? lsize : rsize);
- 
+
 if (res == 0) {
 if (lsize < rsize) {
 	 res = -1;
@@ -2278,8 +2286,8 @@
 	 /* we're in a callback within the DB code, we can't raise */
 	 PyErr_Print();
 	 res = _default_cmp(leftKey, rightKey);
-	} else if (PyInt_Check(result)) {
-	 res = PyInt_AsLong(result);
+	} else if (NUMBER_Check(result)) {
+	 res = NUMBER_AsLong(result);
 	} else {
 	 PyErr_SetString(PyExc_TypeError,
 			 "DB_bt_compare callback MUST return an int.");
@@ -2287,7 +2295,7 @@
 	 PyErr_Print();
 	 res = _default_cmp(leftKey, rightKey);
 	}
- 
+
 	Py_XDECREF(args);
 	Py_XDECREF(result);
 
@@ -2297,15 +2305,11 @@
 }
 
 static PyObject*
-DB_set_bt_compare(DBObject* self, PyObject* args)
+DB_set_bt_compare(DBObject* self, PyObject* comparator)
 {
 int err;
- PyObject *comparator;
 PyObject *tuple, *result;
 
- if (!PyArg_ParseTuple(args, "O:set_bt_compare", &comparator))
-	return NULL;
-
 CHECK_DB_NOT_CLOSED(self);
 
 if (!PyCallable_Check(comparator)) {
@@ -2313,7 +2317,7 @@
 	return NULL;
 }
 
- /* 
+ /*
 * Perform a test call of the comparator function with two empty
 * string objects here. verify that it returns an int (0).
 * err if not.
@@ -2323,11 +2327,11 @@
 Py_DECREF(tuple);
 if (result == NULL)
 return NULL;
- if (!PyInt_Check(result)) {
+ if (!NUMBER_Check(result)) {
 	PyErr_SetString(PyExc_TypeError,
 		 "callback MUST return an int");
 	return NULL;
- } else if (PyInt_AsLong(result) != 0) {
+ } else if (NUMBER_AsLong(result) != 0) {
 	PyErr_SetString(PyExc_TypeError,
 		 "callback failed to return 0 on two empty strings");
 	return NULL;
@@ -2362,7 +2366,6 @@
 RETURN_IF_ERR();
 RETURN_NONE();
 }
-#endif /* DBVER >= 33 */
 
 
 static PyObject*
@@ -2594,10 +2597,8 @@
 MYDB_BEGIN_ALLOW_THREADS;
 #if (DBVER >= 43)
 err = self->db->stat(self->db, txn, &sp, flags);
-#elif (DBVER >= 33)
- err = self->db->stat(self->db, &sp, flags);
 #else
- err = self->db->stat(self->db, &sp, NULL, flags);
+ err = self->db->stat(self->db, &sp, flags);
 #endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
@@ -2674,7 +2675,7 @@
 MAKE_QUEUE_ENTRY(nkeys);
 MAKE_QUEUE_ENTRY(ndata);
 MAKE_QUEUE_ENTRY(pagesize);
-#if (DBVER > 40)
+#if (DBVER >= 41)
 MAKE_QUEUE_ENTRY(extentsize);
 #endif
 MAKE_QUEUE_ENTRY(pages);
@@ -2720,7 +2721,6 @@
 }
 
 
-#if (DBVER >= 33)
 static PyObject*
 DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
 {
@@ -2741,9 +2741,8 @@
 err = self->db->truncate(self->db, txn, &count, flags);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(count);
+ return NUMBER_FromLong(count);
 }
-#endif
 
 
 static PyObject*
@@ -2821,7 +2820,7 @@
 ++oldValue;
 self->moduleFlags.getReturnsNone = (flags >= 1);
 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
- return PyInt_FromLong(oldValue);
+ return NUMBER_FromLong(oldValue);
 }
 
 #if (DBVER >= 41)
@@ -2861,8 +2860,10 @@
 
 if (self->db == NULL) {
 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
- PyErr_SetObject(DBError, t);
- Py_DECREF(t);
+ if (t) {
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ }
 return -1;
 }
 
@@ -2875,10 +2876,8 @@
 redo_stat_for_length:
 #if (DBVER >= 43)
 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, flags);
-#elif (DBVER >= 33)
- err = self->db->stat(self->db, &sp, flags);
 #else
- err = self->db->stat(self->db, &sp, NULL, flags);
+ err = self->db->stat(self->db, &sp, flags);
 #endif
 
 /* All the stat structures have matching fields upto the ndata field,
@@ -2953,8 +2952,10 @@
 
 if (self->db == NULL) {
 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
- PyErr_SetObject(DBError, t);
- Py_DECREF(t);
+ if (t) {
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ }
 return -1;
 }
 
@@ -2997,7 +2998,7 @@
 PyObject* txnobj = NULL;
 DB_TXN *txn = NULL;
 
- if (!PyArg_ParseTuple(args,"O|O:has_key", &keyobj, &txnobj))
+ if (!PyArg_UnpackTuple(args,"has_key", 1, 2, &keyobj, &txnobj))
 return NULL;
 CHECK_DB_NOT_CLOSED(self);
 if (!make_key_dbt(self, keyobj, &key, NULL))
@@ -3020,9 +3021,9 @@
 FREE_DBT(key);
 
 if (err == DB_BUFFER_SMALL || err == 0) {
- return PyInt_FromLong(1);
+ return NUMBER_FromLong(1);
 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
- return PyInt_FromLong(0);
+ return NUMBER_FromLong(0);
 }
 
 makeDBError(err);
@@ -3085,7 +3086,7 @@
 break;
 case DB_RECNO:
 case DB_QUEUE:
- item = PyInt_FromLong(*((db_recno_t*)key.data));
+ item = NUMBER_FromLong(*((db_recno_t*)key.data));
 break;
 }
 break;
@@ -3117,7 +3118,12 @@
 list = NULL;
 goto done;
 }
- PyList_Append(list, item);
+ if (PyList_Append(list, item)) {
+ Py_DECREF(list);
+ Py_DECREF(item);
+ list = NULL;
+ goto done;
+ }
 Py_DECREF(item);
 }
 
@@ -3202,11 +3208,8 @@
 }
 
 static PyObject*
-DBC_close(DBCursorObject* self, PyObject* args)
+DBC_close(DBCursorObject* self)
 {
- if (!PyArg_ParseTuple(args, ":close"))
- return NULL;
-
 return DBC_close_internal(self);
 }
 
@@ -3228,7 +3231,7 @@
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 
- return PyInt_FromLong(count);
+ return NUMBER_FromLong(count);
 }
 
 
@@ -3361,7 +3364,6 @@
 return retval;
 }
 
-#if (DBVER >= 33)
 static PyObject*
 DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
 {
@@ -3427,7 +3429,7 @@
 
 if (self->mydb->primaryDBType == DB_RECNO ||
 self->mydb->primaryDBType == DB_QUEUE)
- pkeyObj = PyInt_FromLong(*(int *)pkey.data);
+ pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
 else
 pkeyObj = Build_PyString(pkey.data, pkey.size);
 
@@ -3436,7 +3438,7 @@
 PyObject *keyObj;
 int type = _DB_get_type(self->mydb);
 if (type == DB_RECNO || type == DB_QUEUE)
- keyObj = PyInt_FromLong(*(int *)key.data);
+ keyObj = NUMBER_FromLong(*(int *)key.data);
 else
 keyObj = Build_PyString(key.data, key.size);
 #if (PY_VERSION_HEX >= 0x02040000)
@@ -3466,20 +3468,16 @@
 }
 return retval;
 }
-#endif
 
 
 static PyObject*
-DBC_get_recno(DBCursorObject* self, PyObject* args)
+DBC_get_recno(DBCursorObject* self)
 {
 int err;
 db_recno_t recno;
 DBT key;
 DBT data;
 
- if (!PyArg_ParseTuple(args, ":get_recno"))
- return NULL;
-
 CHECK_CURSOR_NOT_CLOSED(self);
 
 CLEAR_DBT(key);
@@ -3491,7 +3489,7 @@
 RETURN_IF_ERR();
 
 recno = *((db_recno_t*)data.data);
- return PyInt_FromLong(recno);
+ return NUMBER_FromLong(recno);
 }
 
 
@@ -3741,14 +3739,12 @@
 
 /* Return size of entry */
 static PyObject*
-DBC_get_current_size(DBCursorObject* self, PyObject* args)
+DBC_get_current_size(DBCursorObject* self)
 {
 int err, flags=DB_CURRENT;
 PyObject* retval = NULL;
 DBT key, data;
 
- if (!PyArg_ParseTuple(args, ":get_current_size"))
- return NULL;
 CHECK_CURSOR_NOT_CLOSED(self);
 CLEAR_DBT(key);
 CLEAR_DBT(data);
@@ -3762,7 +3758,7 @@
 MYDB_END_ALLOW_THREADS;
 if (err == DB_BUFFER_SMALL || !err) {
 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
- retval = PyInt_FromLong((long)data.size);
+ retval = NUMBER_FromLong((long)data.size);
 err = 0;
 }
 
@@ -4066,7 +4062,6 @@
 }
 #endif /* DBVER >= 41 */
 
-#if (DBVER >= 40)
 static PyObject*
 DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
 {
@@ -4087,7 +4082,6 @@
 RETURN_IF_ERR();
 RETURN_NONE();
 }
-#endif /* DBVER >= 40 */
 
 static PyObject*
 DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
@@ -4230,25 +4224,22 @@
 
 #if (DBVER >= 42)
 static PyObject*
-DBEnv_get_lg_max(DBEnvObject* self, PyObject* args)
+DBEnv_get_lg_max(DBEnvObject* self)
 {
 int err;
 u_int32_t lg_max;
 
- if (!PyArg_ParseTuple(args, ":get_lg_max"))
- return NULL;
 CHECK_ENV_NOT_CLOSED(self);
 
 MYDB_BEGIN_ALLOW_THREADS;
 err = self->db_env->get_lg_max(self->db_env, &lg_max);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(lg_max);
+ return NUMBER_FromLong(lg_max);
 }
 #endif
 
 
-#if (DBVER >= 33)
 static PyObject*
 DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
 {
@@ -4264,7 +4255,6 @@
 RETURN_IF_ERR();
 RETURN_NONE();
 }
-#endif
 
 
 static PyObject*
@@ -4390,9 +4380,8 @@
 }
 
 
-#if (DBVER >= 40)
 static PyObject*
-DBEnv_txn_recover(DBEnvObject* self, PyObject* args)
+DBEnv_txn_recover(DBEnvObject* self)
 {
 int flags = DB_FIRST;
 int err, i;
@@ -4402,9 +4391,6 @@
 DB_PREPLIST preplist[PREPLIST_LEN];
 long retp;
 
- if (!PyArg_ParseTuple(args, ":txn_recover"))
- return NULL;
-
 CHECK_ENV_NOT_CLOSED(self);
 
 list=PyList_New(0);
@@ -4466,7 +4452,6 @@
 }
 return list;
 }
-#endif
 
 static PyObject*
 DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
@@ -4498,11 +4483,7 @@
 CHECK_ENV_NOT_CLOSED(self);
 
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
-#else
- err = txn_checkpoint(self->db_env, kbyte, min, flags);
-#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 RETURN_NONE();
@@ -4552,14 +4533,10 @@
 CHECK_ENV_NOT_CLOSED(self);
 
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
-#else
- err = lock_detect(self->db_env, flags, atype, &aborted);
-#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(aborted);
+ return NUMBER_FromLong(aborted);
 }
 
 
@@ -4583,28 +4560,20 @@
 
 
 static PyObject*
-DBEnv_lock_id(DBEnvObject* self, PyObject* args)
+DBEnv_lock_id(DBEnvObject* self)
 {
 int err;
 u_int32_t theID;
 
- if (!PyArg_ParseTuple(args, ":lock_id"))
- return NULL;
-
 CHECK_ENV_NOT_CLOSED(self);
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = self->db_env->lock_id(self->db_env, &theID);
-#else
- err = lock_id(self->db_env, &theID);
-#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 
- return PyInt_FromLong((long)theID);
+ return NUMBER_FromLong((long)theID);
 }
 
-#if (DBVER >= 40)
 static PyObject*
 DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
 {
@@ -4621,7 +4590,6 @@
 RETURN_IF_ERR();
 RETURN_NONE();
 }
-#endif
 
 static PyObject*
 DBEnv_lock_put(DBEnvObject* self, PyObject* args)
@@ -4634,11 +4602,7 @@
 
 CHECK_ENV_NOT_CLOSED(self);
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
-#else
- err = lock_put(self->db_env, &dblockobj->lock);
-#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 RETURN_NONE();
@@ -4666,7 +4630,6 @@
 }
 #endif /* DBVER >= 4.4 */
 
-#if (DBVER >= 40)
 static PyObject*
 DBEnv_log_stat(DBEnvObject* self, PyObject* args)
 {
@@ -4702,7 +4665,7 @@
 MAKE_ENTRY(lg_size);
 MAKE_ENTRY(record);
 #endif
-#if (DBVER <= 40)
+#if (DBVER < 41)
 MAKE_ENTRY(lg_max);
 #endif
 MAKE_ENTRY(w_mbytes);
@@ -4729,7 +4692,6 @@
 free(statp);
 return d;
 } /* DBEnv_log_stat */
-#endif /* DBVER >= 4.0 for log_stat method */
 
 
 static PyObject*
@@ -4745,15 +4707,7 @@
 CHECK_ENV_NOT_CLOSED(self);
 
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = self->db_env->lock_stat(self->db_env, &sp, flags);
-#else
-#if (DBVER >= 33)
- err = lock_stat(self->db_env, &sp);
-#else
- err = lock_stat(self->db_env, &sp, NULL);
-#endif
-#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 
@@ -4801,10 +4755,8 @@
 MAKE_ENTRY(locktimeout);
 MAKE_ENTRY(txntimeout);
 #endif
-#if (DBVER >= 40)
 MAKE_ENTRY(nlocktimeouts);
 MAKE_ENTRY(ntxntimeouts);
-#endif
 #if (DBVER >= 46)
 MAKE_ENTRY(objs_wait);
 MAKE_ENTRY(objs_nowait);
@@ -4828,14 +4780,11 @@
 return d;
 }
 
-#if (DBVER >= 40)
 static PyObject*
-DBEnv_log_flush(DBEnvObject* self, PyObject* args)
+DBEnv_log_flush(DBEnvObject* self)
 {
 int err;
 
- if (!PyArg_ParseTuple(args, ":log_flush"))
- return NULL;
 CHECK_ENV_NOT_CLOSED(self);
 
 MYDB_BEGIN_ALLOW_THREADS
@@ -4845,7 +4794,6 @@
 RETURN_IF_ERR();
 RETURN_NONE();
 }
-#endif
 
 static PyObject*
 DBEnv_log_archive(DBEnvObject* self, PyObject* args)
@@ -4861,13 +4809,7 @@
 
 CHECK_ENV_NOT_CLOSED(self);
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = self->db_env->log_archive(self->db_env, &log_list, flags);
-#elif (DBVER == 33)
- err = log_archive(self->db_env, &log_list, flags);
-#else
- err = log_archive(self->db_env, &log_list, flags, NULL);
-#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 
@@ -4887,7 +4829,12 @@
 list = NULL;
 break;
 }
- PyList_Append(list, item);
+ if (PyList_Append(list, item)) {
+ Py_DECREF(list);
+ list = NULL;
+ Py_DECREF(item);
+ break;
+ }
 Py_DECREF(item);
 }
 free(log_list_start);
@@ -4909,13 +4856,7 @@
 CHECK_ENV_NOT_CLOSED(self);
 
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = self->db_env->txn_stat(self->db_env, &sp, flags);
-#elif (DBVER == 33)
- err = txn_stat(self->db_env, &sp);
-#else
- err = txn_stat(self->db_env, &sp, NULL);
-#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 
@@ -4930,9 +4871,7 @@
 #define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
 #define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
 
-#if (DBVER >= 40)
 MAKE_DB_LSN_ENTRY(last_ckp);
-#endif
 MAKE_TIME_T_ENTRY(time_ckp);
 MAKE_ENTRY(last_txnid);
 MAKE_ENTRY(maxtxns);
@@ -4945,9 +4884,7 @@
 MAKE_ENTRY(nbegins);
 MAKE_ENTRY(naborts);
 MAKE_ENTRY(ncommits);
-#if (DBVER >= 40)
 MAKE_ENTRY(nrestores);
-#endif
 MAKE_ENTRY(regsize);
 MAKE_ENTRY(region_wait);
 MAKE_ENTRY(region_nowait);
@@ -4976,10 +4913,28 @@
 ++oldValue;
 self->moduleFlags.getReturnsNone = (flags >= 1);
 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
- return PyInt_FromLong(oldValue);
+ return NUMBER_FromLong(oldValue);
+}
+
+static PyObject*
+DBEnv_get_private(DBEnvObject* self)
+{
+ /* We can give out the private field even if dbenv is closed */
+ Py_INCREF(self->private);
+ return self->private;
+}
+
+static PyObject*
+DBEnv_set_private(DBEnvObject* self, PyObject* private)
+{
+ /* We can set the private field even if dbenv is closed */
+ Py_DECREF(self->private);
+ Py_INCREF(private);
+ self->private = private;
+ RETURN_NONE();
 }
 
-#if (DBVER >= 40)
+
 static PyObject*
 DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
 {
@@ -5001,9 +4956,7 @@
 RETURN_IF_ERR();
 RETURN_NONE();
 }
-#endif
 
-#if (DBVER >= 40)
 static PyObject*
 DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
 {
@@ -5040,7 +4993,6 @@
 return PyBool_FromLong(verbose);
 }
 #endif
-#endif
 
 #if (DBVER >= 45)
 static void
@@ -5075,14 +5027,9 @@
 
 #if (DBVER >= 45)
 static PyObject*
-DBEnv_set_event_notify(DBEnvObject* self, PyObject* args)
+DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
 {
 int err;
- PyObject *notifyFunc;
-
- if (!PyArg_ParseTuple(args, "O:set_event_notify", &notifyFunc)) {
-	 return NULL;
- }
 
 CHECK_ENV_NOT_CLOSED(self);
 
@@ -5095,6 +5042,12 @@
 Py_INCREF(notifyFunc);
 self->event_notifyCallback = notifyFunc;
 
+ /* This is to workaround a problem with un-initialized threads (see
+ comment in DB_associate) */
+#ifdef WITH_THREAD
+ PyEval_InitThreads();
+#endif
+
 MYDB_BEGIN_ALLOW_THREADS;
 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
 MYDB_END_ALLOW_THREADS;
@@ -5113,146 +5066,461 @@
 /* --------------------------------------------------------------------- */
 /* REPLICATION METHODS: Base Replication */
 
-#if (DBVER >= 45)
+
 static PyObject*
-DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
+DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
 {
 int err;
- int nsites;
+ PyObject *control_py, *rec_py;
+ DBT control, rec;
+ int envid;
+#if (DBVER >= 42)
+ DB_LSN lsn;
+#endif
 
- if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
+ if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
+ &rec_py, &envid))
 return NULL;
- }
 CHECK_ENV_NOT_CLOSED(self);
+
+ if (!make_dbt(control_py, &control))
+ return NULL;
+ if (!make_dbt(rec_py, &rec))
+ return NULL;
+
 MYDB_BEGIN_ALLOW_THREADS;
- err = self->db_env->rep_set_nsites(self->db_env, nsites);
+#if (DBVER >= 46)
+ err = self->db_env->rep_process_message(self->db_env, &control, &rec,
+ envid, &lsn);
+#else
+#if (DBVER >= 42)
+ err = self->db_env->rep_process_message(self->db_env, &control, &rec,
+ &envid, &lsn);
+#else
+ err = self->db_env->rep_process_message(self->db_env, &control, &rec,
+ &envid);
+#endif
+#endif
 MYDB_END_ALLOW_THREADS;
+ switch (err) {
+ case DB_REP_NEWMASTER :
+ return Py_BuildValue("(iO)", envid, Py_None);
+ break;
+
+ case DB_REP_DUPMASTER :
+ case DB_REP_HOLDELECTION :
+#if (DBVER >= 44)
+ case DB_REP_IGNORE :
+ case DB_REP_JOIN_FAILURE :
+#endif
+ return Py_BuildValue("(iO)", err, Py_None);
+ break;
+ case DB_REP_NEWSITE :
+ return Py_BuildValue("(is#)", err, rec.data, rec.size);
+ break;
+#if (DBVER >= 42)
+ case DB_REP_NOTPERM :
+ case DB_REP_ISPERM :
+ return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
+ break;
+#endif
+ }
 RETURN_IF_ERR();
- RETURN_NONE();
+ return Py_BuildValue("(OO)", Py_None, Py_None);
 }
 
-static PyObject*
-DBEnv_rep_get_nsites(DBEnvObject* self, PyObject* args)
+static int
+_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
+ const DB_LSN *lsn, int envid, u_int32_t flags)
 {
- int err;
-#if (DBVER >= 47)
- u_int32_t nsites;
+ DBEnvObject *dbenv;
+ PyObject* rep_transport;
+ PyObject* args;
+ PyObject* result = NULL;
+ int ret=0;
+
+ MYDB_BEGIN_BLOCK_THREADS;
+ dbenv = (DBEnvObject *)db_env->app_private;
+ rep_transport = dbenv->rep_transport;
+
+ args = Py_BuildValue(
+#if (PY_VERSION_HEX >= 0x02040000)
+ "(Os#s#(ll)iI)",
 #else
- int nsites;
+ "(Os#s#(ll)ii)",
 #endif
+ dbenv,
+ control->data, control->size,
+ rec->data, rec->size, lsn->file, lsn->offset, envid, flags);
+ if (args) {
+ result = PyEval_CallObject(rep_transport, args);
+ }
 
- if (!PyArg_ParseTuple(args, ":rep_get_nsites")) {
- return NULL;
+ if ((!args) || (!result)) {
+ PyErr_Print();
+ ret = -1;
 }
+ Py_XDECREF(args);
+ Py_XDECREF(result);
+ MYDB_END_BLOCK_THREADS;
+ return ret;
+}
+
+#if (DBVER <= 41)
+static int
+_DBEnv_rep_transportCallbackOLD(DB_ENV* db_env, const DBT* control, const DBT* rec,
+ int envid, u_int32_t flags)
+{
+ DB_LSN lsn;
+
+ lsn.file = -1; /* Dummy values */
+ lsn.offset = -1;
+ return _DBEnv_rep_transportCallback(db_env, control, rec, &lsn, envid,
+ flags);
+}
+#endif
+
+static PyObject*
+DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int envid;
+ PyObject *rep_transport;
+
+ if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
+ return NULL;
 CHECK_ENV_NOT_CLOSED(self);
+ if (!PyCallable_Check(rep_transport)) {
+ makeTypeError("Callable", rep_transport);
+ return NULL;
+ }
+
 MYDB_BEGIN_ALLOW_THREADS;
- err = self->db_env->rep_get_nsites(self->db_env, &nsites);
+#if (DBVER >=45)
+ err = self->db_env->rep_set_transport(self->db_env, envid,
+ &_DBEnv_rep_transportCallback);
+#else
+#if (DBVER >= 42)
+ err = self->db_env->set_rep_transport(self->db_env, envid,
+ &_DBEnv_rep_transportCallback);
+#else
+ err = self->db_env->set_rep_transport(self->db_env, envid,
+ &_DBEnv_rep_transportCallbackOLD);
+#endif
+#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(nsites);
+
+ Py_DECREF(self->rep_transport);
+ Py_INCREF(rep_transport);
+ self->rep_transport = rep_transport;
+ RETURN_NONE();
 }
 
+#if (DBVER >= 47)
 static PyObject*
-DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
+DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
 {
 int err;
- int priority;
+ unsigned int minimum, maximum;
 
- if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
+ if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
 return NULL;
- }
 CHECK_ENV_NOT_CLOSED(self);
+
 MYDB_BEGIN_ALLOW_THREADS;
- err = self->db_env->rep_set_priority(self->db_env, priority);
+ err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 RETURN_NONE();
 }
 
 static PyObject*
-DBEnv_rep_get_priority(DBEnvObject* self, PyObject* args)
+DBEnv_rep_get_request(DBEnvObject* self)
 {
 int err;
-#if (DBVER >= 47)
- u_int32_t priority;
-#else
- int priority;
-#endif
+ u_int32_t minimum, maximum;
 
- if (!PyArg_ParseTuple(args, ":rep_get_priority")) {
- return NULL;
- }
 CHECK_ENV_NOT_CLOSED(self);
 MYDB_BEGIN_ALLOW_THREADS;
- err = self->db_env->rep_get_priority(self->db_env, &priority);
+ err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(priority);
+#if (PY_VERSION_HEX >= 0x02040000)
+ return Py_BuildValue("II", minimum, maximum);
+#else
+ return Py_BuildValue("ii", minimum, maximum);
+#endif
 }
+#endif
 
+#if (DBVER >= 45)
 static PyObject*
-DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
+DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
 {
 int err;
- int which, timeout;
+ int limit;
 
- if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
+ if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
 return NULL;
- }
 CHECK_ENV_NOT_CLOSED(self);
+
 MYDB_BEGIN_ALLOW_THREADS;
- err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
+ err = self->db_env->rep_set_limit(self->db_env, 0, limit);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 RETURN_NONE();
 }
 
 static PyObject*
-DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
+DBEnv_rep_get_limit(DBEnvObject* self)
 {
 int err;
- int which;
- u_int32_t timeout;
+ u_int32_t gbytes, bytes;
 
- if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
- return NULL;
- }
 CHECK_ENV_NOT_CLOSED(self);
 MYDB_BEGIN_ALLOW_THREADS;
- err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
+ err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(timeout);
+ return NUMBER_FromLong(bytes);
 }
 #endif
 
-/* --------------------------------------------------------------------- */
-/* REPLICATION METHODS: Replication Manager */
-
-#if (DBVER >= 45)
+#if (DBVER >= 44)
 static PyObject*
-DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
- kwargs)
+DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
 {
 int err;
- int nthreads, flags;
- static char* kwnames[] = {"nthreads","flags", NULL};
+ int which;
+ int onoff;
 
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "ii:repmgr_start", kwnames, &nthreads, &flags))
- {
-	 return NULL;
- }
+ if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
+ return NULL;
 CHECK_ENV_NOT_CLOSED(self);
+
 MYDB_BEGIN_ALLOW_THREADS;
- err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
+ err = self->db_env->rep_set_config(self->db_env, which, onoff);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 RETURN_NONE();
 }
 
 static PyObject*
-DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
+DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int which;
+ int onoff;
+
+ if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_get_config(self->db_env, which, &onoff);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return PyBool_FromLong(onoff);
+}
+#endif
+
+#if (DBVER >= 46)
+static PyObject*
+DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ u_int32_t nsites, nvotes;
+
+ if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_elect(self->db_env, nvotes, nvotes, 0);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif
+
+static PyObject*
+DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
+{
+ int err;
+ PyObject *cdata_py = Py_None;
+ DBT cdata;
+ int flags;
+ static char* kwnames[] = {"flags","cdata", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "i|O:rep_start", kwnames, &flags, &cdata_py))
+ {
+	 return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+
+ if (!make_dbt(cdata_py, &cdata))
+ return NULL;
+
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
+ flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+#if (DBVER >= 44)
+static PyObject*
+DBEnv_rep_sync(DBEnvObject* self)
+{
+ int err;
+
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_sync(self->db_env, 0);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+#endif
+
+
+#if (DBVER >= 45)
+static PyObject*
+DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int nsites;
+
+ if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_set_nsites(self->db_env, nsites);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_rep_get_nsites(DBEnvObject* self)
+{
+ int err;
+#if (DBVER >= 47)
+ u_int32_t nsites;
+#else
+ int nsites;
+#endif
+
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_get_nsites(self->db_env, &nsites);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return NUMBER_FromLong(nsites);
+}
+
+static PyObject*
+DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int priority;
+
+ if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_set_priority(self->db_env, priority);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_rep_get_priority(DBEnvObject* self)
+{
+ int err;
+#if (DBVER >= 47)
+ u_int32_t priority;
+#else
+ int priority;
+#endif
+
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_get_priority(self->db_env, &priority);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return NUMBER_FromLong(priority);
+}
+
+static PyObject*
+DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int which, timeout;
+
+ if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
+{
+ int err;
+ int which;
+ u_int32_t timeout;
+
+ if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
+ return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ return NUMBER_FromLong(timeout);
+}
+#endif
+
+/* --------------------------------------------------------------------- */
+/* REPLICATION METHODS: Replication Manager */
+
+#if (DBVER >= 45)
+static PyObject*
+DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
+ kwargs)
+{
+ int err;
+ int nthreads, flags;
+ static char* kwnames[] = {"nthreads","flags", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "ii:repmgr_start", kwnames, &nthreads, &flags))
+ {
+	 return NULL;
+ }
+ CHECK_ENV_NOT_CLOSED(self);
+ MYDB_BEGIN_ALLOW_THREADS;
+ err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
+ MYDB_END_ALLOW_THREADS;
+ RETURN_IF_ERR();
+ RETURN_NONE();
+}
+
+static PyObject*
+DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
 kwargs)
 {
 int err;
@@ -5295,7 +5563,7 @@
 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(eidp);
+ return NUMBER_FromLong(eidp);
 }
 
 static PyObject*
@@ -5317,35 +5585,27 @@
 }
 
 static PyObject*
-DBEnv_repmgr_get_ack_policy(DBEnvObject* self, PyObject* args)
+DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
 {
 int err;
 int ack_policy;
 
- if (!PyArg_ParseTuple(args, ":repmgr_get_ack_policy"))
- {
-	 return NULL;
- }
 CHECK_ENV_NOT_CLOSED(self);
 MYDB_BEGIN_ALLOW_THREADS;
 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
- return PyInt_FromLong(ack_policy);
+ return NUMBER_FromLong(ack_policy);
 }
 
 static PyObject*
-DBEnv_repmgr_site_list(DBEnvObject* self, PyObject* args)
+DBEnv_repmgr_site_list(DBEnvObject* self)
 {
 int err;
 unsigned int countp;
 DB_REPMGR_SITE *listp;
 PyObject *stats, *key, *tuple;
 
- if (!PyArg_ParseTuple(args, ":repmgr_site_list"))
- {
- return NULL;
- }
 CHECK_ENV_NOT_CLOSED(self);
 MYDB_BEGIN_ALLOW_THREADS;
 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
@@ -5359,7 +5619,7 @@
 }
 
 for(;countp--;) {
- key=PyInt_FromLong(listp[countp].eid);
+ key=NUMBER_FromLong(listp[countp].eid);
 if(!key) {
 Py_DECREF(stats);
 free(listp);
@@ -5524,8 +5784,10 @@
 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
 "after txn_commit, txn_abort "
 "or txn_discard");
- PyErr_SetObject(DBError, t);
- Py_DECREF(t);
+ if (t) {
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ }
 return NULL;
 }
 self->flag_prepare=0;
@@ -5535,11 +5797,7 @@
 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
 
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = txn->commit(txn, flags);
-#else
- err = txn_commit(txn, flags);
-#endif
 MYDB_END_ALLOW_THREADS;
 
 _promote_transaction_dbs_and_sequences(self);
@@ -5551,7 +5809,6 @@
 static PyObject*
 DBTxn_prepare(DBTxnObject* self, PyObject* args)
 {
-#if (DBVER >= 33)
 int err;
 char* gid=NULL;
 int gid_size=0;
@@ -5569,40 +5826,18 @@
 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
 "after txn_commit, txn_abort "
 "or txn_discard");
- PyErr_SetObject(DBError, t);
- Py_DECREF(t);
+ if (t) {
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ }
 return NULL;
 }
 self->flag_prepare=1; /* Prepare state */
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
-#else
- err = txn_prepare(self->txn, (u_int8_t*)gid);
-#endif
 MYDB_END_ALLOW_THREADS;
 RETURN_IF_ERR();
 RETURN_NONE();
-#else
- int err;
-
- if (!PyArg_ParseTuple(args, ":prepare"))
- return NULL;
-
- if (!self->txn) {
- PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
- "after txn_commit, txn_abort "
- "or txn_discard");
- PyErr_SetObject(DBError, t);
- Py_DECREF(t);
- return NULL;
- }
- MYDB_BEGIN_ALLOW_THREADS;
- err = txn_prepare(self->txn);
- MYDB_END_ALLOW_THREADS;
- RETURN_IF_ERR();
- RETURN_NONE();
-#endif
 }
 
 
@@ -5617,8 +5852,10 @@
 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
 "after txn_commit, txn_abort "
 "or txn_discard");
- PyErr_SetObject(DBError, t);
- Py_DECREF(t);
+ if (t) {
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ }
 return NULL;
 }
 txn = self->txn;
@@ -5641,22 +5878,14 @@
 MYDB_BEGIN_ALLOW_THREADS;
 if (discard) {
 assert(!self->flag_prepare);
-#if (DBVER >= 40)
 err = txn->discard(txn,0);
-#else
- err = txn_discard(txn);
-#endif
 } else {
 /*
 ** If the transaction is in the "prepare" or "recover" state,
 ** we better do not implicitly abort it.
 */
 if (!self->flag_prepare) {
-#if (DBVER >= 40)
 err = txn->abort(txn);
-#else
- err = txn_abort(txn);
-#endif
 }
 }
 MYDB_END_ALLOW_THREADS;
@@ -5665,11 +5894,8 @@
 }
 
 static PyObject*
-DBTxn_abort(DBTxnObject* self, PyObject* args)
+DBTxn_abort(DBTxnObject* self)
 {
- if (!PyArg_ParseTuple(args, ":abort"))
- return NULL;
-
 self->flag_prepare=0;
 _close_transaction_cursors(self);
 
@@ -5677,11 +5903,8 @@
 }
 
 static PyObject*
-DBTxn_discard(DBTxnObject* self, PyObject* args)
+DBTxn_discard(DBTxnObject* self)
 {
- if (!PyArg_ParseTuple(args, ":discard"))
- return NULL;
-
 self->flag_prepare=0;
 _close_transaction_cursors(self);
 
@@ -5690,29 +5913,24 @@
 
 
 static PyObject*
-DBTxn_id(DBTxnObject* self, PyObject* args)
+DBTxn_id(DBTxnObject* self)
 {
 int id;
 
- if (!PyArg_ParseTuple(args, ":id"))
- return NULL;
-
 if (!self->txn) {
 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
 "after txn_commit, txn_abort "
 "or txn_discard");
- PyErr_SetObject(DBError, t);
- Py_DECREF(t);
+ if (t) {
+ PyErr_SetObject(DBError, t);
+ Py_DECREF(t);
+ }
 return NULL;
 }
 MYDB_BEGIN_ALLOW_THREADS;
-#if (DBVER >= 40)
 id = self->txn->id(self->txn);
-#else
- id = txn_id(self->txn);
-#endif
 MYDB_END_ALLOW_THREADS;
- return PyInt_FromLong(id);
+ return NUMBER_FromLong(id);
 }
 
 #if (DBVER >= 43)
@@ -5780,25 +5998,20 @@
 }
 
 static PyObject*
-DBSequence_get_dbp(DBSequenceObject* self, PyObject* args)
+DBSequence_get_dbp(DBSequenceObject* self)
 {
- if (!PyArg_ParseTuple(args,":get_dbp"))
- return NULL;
 CHECK_SEQUENCE_NOT_CLOSED(self)
 Py_INCREF(self->mydb);
 return (PyObject* )self->mydb;
 }
 
 static PyObject*
-DBSequence_get_key(DBSequenceObject* self, PyObject* args)
+DBSequence_get_key(DBSequenceObject* self)
 {
 int err;
 DBT key;
 PyObject *retval = NULL;
 
- if (!PyArg_ParseTuple(args,":get_key"))
- return NULL;
-
 key.flags = DB_DBT_MALLOC;
 CHECK_SEQUENCE_NOT_CLOSED(self)
 MYDB_BEGIN_ALLOW_THREADS
@@ -5806,7 +6019,7 @@
 MYDB_END_ALLOW_THREADS
 
 if (!err)
- retval = Build_PyString(key.data, key.size); 
+ retval = Build_PyString(key.data, key.size);
 
 FREE_DBT(key);
 RETURN_IF_ERR();
@@ -5913,11 +6126,10 @@
 }
 
 static PyObject*
-DBSequence_get_cachesize(DBSequenceObject* self, PyObject* args)
+DBSequence_get_cachesize(DBSequenceObject* self)
 {
 int err, size;
- if (!PyArg_ParseTuple(args,":get_cachesize"))
- return NULL;
+
 CHECK_SEQUENCE_NOT_CLOSED(self)
 
 MYDB_BEGIN_ALLOW_THREADS
@@ -5925,7 +6137,7 @@
 MYDB_END_ALLOW_THREADS
 
 RETURN_IF_ERR();
- return PyInt_FromLong(size);
+ return NUMBER_FromLong(size);
 }
 
 static PyObject*
@@ -5945,12 +6157,11 @@
 }
 
 static PyObject*
-DBSequence_get_flags(DBSequenceObject* self, PyObject* args)
+DBSequence_get_flags(DBSequenceObject* self)
 {
 unsigned int flags;
 int err;
- if (!PyArg_ParseTuple(args,":get_flags"))
- return NULL;
+
 CHECK_SEQUENCE_NOT_CLOSED(self)
 
 MYDB_BEGIN_ALLOW_THREADS
@@ -5958,7 +6169,7 @@
 MYDB_END_ALLOW_THREADS
 
 RETURN_IF_ERR();
- return PyInt_FromLong((int)flags);
+ return NUMBER_FromLong((int)flags);
 }
 
 static PyObject*
@@ -5982,13 +6193,12 @@
 }
 
 static PyObject*
-DBSequence_get_range(DBSequenceObject* self, PyObject* args)
+DBSequence_get_range(DBSequenceObject* self)
 {
 int err;
 PY_LONG_LONG min, max;
 db_seq_t min2, max2;
- if (!PyArg_ParseTuple(args,":get_range"))
- return NULL;
+
 CHECK_SEQUENCE_NOT_CLOSED(self)
 
 MYDB_BEGIN_ALLOW_THREADS
@@ -6050,23 +6260,19 @@
 
 static PyMethodDef DB_methods[] = {
 {"append", (PyCFunction)DB_append, METH_VARARGS},
-#if (DBVER >= 33)
 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
-#endif
 {"close", (PyCFunction)DB_close, METH_VARARGS},
 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
- {"fd", (PyCFunction)DB_fd, METH_VARARGS},
+ {"fd", (PyCFunction)DB_fd, METH_NOARGS},
 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
-#if (DBVER >= 33)
 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
-#endif
 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
- {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_VARARGS},
+ {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
- {"get_type", (PyCFunction)DB_get_type, METH_VARARGS},
+ {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
 {"join", (PyCFunction)DB_join, METH_VARARGS},
 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS},
@@ -6077,9 +6283,7 @@
 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
-#if (DBVER >= 33)
- {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_VARARGS},
-#endif
+ {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
 #if (DBVER >= 41)
 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
@@ -6093,13 +6297,13 @@
 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
- {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize,METH_VARARGS},
+ {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
+ {"set_private", (PyCFunction)DB_set_private, METH_O},
+ {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
-#if (DBVER >= 33)
 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
-#endif
- {"type", (PyCFunction)DB_get_type, METH_VARARGS},
+ {"type", (PyCFunction)DB_get_type, METH_NOARGS},
 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
 {"values", (PyCFunction)DB_values, METH_VARARGS},
 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
@@ -6116,17 +6320,15 @@
 
 
 static PyMethodDef DBCursor_methods[] = {
- {"close", (PyCFunction)DBC_close, METH_VARARGS},
+ {"close", (PyCFunction)DBC_close, METH_NOARGS},
 {"count", (PyCFunction)DBC_count, METH_VARARGS},
 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
-#if (DBVER >= 33)
 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
-#endif
- {"get_recno", (PyCFunction)DBC_get_recno, METH_VARARGS},
+ {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
@@ -6134,7 +6336,7 @@
 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
- {"get_current_size",(PyCFunction)DBC_get_current_size, METH_VARARGS},
+ {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
@@ -6155,9 +6357,7 @@
 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
 #endif
-#if (DBVER >= 40)
 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
-#endif
 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
@@ -6169,11 +6369,9 @@
 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
 #if (DBVER >= 42)
- {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_VARARGS},
+ {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
 #endif
-#if (DBVER >= 33)
 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
-#endif
 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
 #if (DBVER < 45)
 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
@@ -6190,44 +6388,55 @@
 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
- {"lock_id", (PyCFunction)DBEnv_lock_id, METH_VARARGS},
-#if (DBVER >= 40)
+ {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
-#endif
 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
-#if (DBVER >= 40)
- {"log_flush", (PyCFunction)DBEnv_log_flush, METH_VARARGS},
-#endif
-#if (DBVER >= 40)
+ {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
-#endif
 #if (DBVER >= 44)
 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
 #endif
 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
-#if (DBVER >= 40)
- {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_VARARGS},
-#endif
-#if (DBVER >= 40)
+ {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
 METH_VARARGS||METH_KEYWORDS},
-#endif
-#if (DBVER >= 40)
 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
 #if (DBVER >= 42)
 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
 #endif
+ {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
+ {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
+ {"rep_start", (PyCFunction)DBEnv_rep_start,
+ METH_VARARGS|METH_KEYWORDS},
+ {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
+ {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
+ METH_VARARGS},
+#if (DBVER >= 46)
+ {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
+#endif
+#if (DBVER >= 44)
+ {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
+ {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
+ {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
+#endif
+#if (DBVER >= 45)
+ {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
+ {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
+#endif
+#if (DBVER >= 47)
+ {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
+ {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
 #endif
 #if (DBVER >= 45)
- {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_VARARGS},
+ {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
 #endif
 #if (DBVER >= 45)
 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
- {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_VARARGS},
+ {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
- {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_VARARGS},
+ {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
 #endif
@@ -6241,9 +6450,9 @@
 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
 METH_VARARGS},
 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
- METH_VARARGS},
+ METH_NOARGS},
 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
- METH_VARARGS},
+ METH_NOARGS},
 #endif
 #if (DBVER >= 46)
 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
@@ -6258,9 +6467,9 @@
 static PyMethodDef DBTxn_methods[] = {
 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
- {"discard", (PyCFunction)DBTxn_discard, METH_VARARGS},
- {"abort", (PyCFunction)DBTxn_abort, METH_VARARGS},
- {"id", (PyCFunction)DBTxn_id, METH_VARARGS},
+ {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
+ {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
+ {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
 {NULL, NULL} /* sentinel */
 };
 
@@ -6269,17 +6478,17 @@
 static PyMethodDef DBSequence_methods[] = {
 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
- {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_VARARGS},
- {"get_key", (PyCFunction)DBSequence_get_key, METH_VARARGS},
+ {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
+ {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
 {"init_value", (PyCFunction)DBSequence_init_value, METH_VARARGS},
 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
- {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_VARARGS},
+ {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
- {"get_flags", (PyCFunction)DBSequence_get_flags, METH_VARARGS},
+ {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
- {"get_range", (PyCFunction)DBSequence_get_range, METH_VARARGS},
+ {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
 {NULL, NULL} /* sentinel */
 };
@@ -6287,70 +6496,45 @@
 
 
 static PyObject*
-DB_getattr(DBObject* self, char *name)
+DBEnv_db_home_get(DBEnvObject* self)
 {
- return Py_FindMethod(DB_methods, (PyObject* )self, name);
-}
+ const char *home = NULL;
 
+ CHECK_ENV_NOT_CLOSED(self);
 
-static PyObject*
-DBEnv_getattr(DBEnvObject* self, char *name)
-{
- if (!strcmp(name, "db_home")) {
- const char *home = NULL;
- CHECK_ENV_NOT_CLOSED(self);
 #if (DBVER >= 42)
- self->db_env->get_home(self->db_env, &home);
+ self->db_env->get_home(self->db_env, &home);
 #else
- home=self->db_env->db_home;
+ home=self->db_env->db_home;
 #endif
- if (home == NULL) {
- RETURN_NONE();
- }
- return PyBytes_FromString(home);
- }
-
- return Py_FindMethod(DBEnv_methods, (PyObject* )self, name);
-}
-
-
-static PyObject*
-DBCursor_getattr(DBCursorObject* self, char *name)
-{
- return Py_FindMethod(DBCursor_methods, (PyObject* )self, name);
-}
 
-static PyObject*
-DBTxn_getattr(DBTxnObject* self, char *name)
-{
- return Py_FindMethod(DBTxn_methods, (PyObject* )self, name);
+ if (home == NULL) {
+ RETURN_NONE();
+ }
+ return PyBytes_FromString(home);
 }
 
-static PyObject*
-DBLock_getattr(DBLockObject* self, char *name)
-{
- return NULL;
-}
+static PyGetSetDef DBEnv_getsets[] = {
+ {"db_home", (getter)DBEnv_db_home_get, NULL,},
+ {NULL}
+};
 
-#if (DBVER >= 43)
-static PyObject*
-DBSequence_getattr(DBSequenceObject* self, char *name)
-{
- return Py_FindMethod(DBSequence_methods, (PyObject* )self, name);
-}
-#endif
 
 statichere PyTypeObject DB_Type = {
+#if (PY_VERSION_HEX < 0x03000000)
 PyObject_HEAD_INIT(NULL)
 0, /*ob_size*/
+#else
+ PyVarObject_HEAD_INIT(NULL, 0)
+#endif
 "DB", /*tp_name*/
 sizeof(DBObject), /*tp_basicsize*/
 0, /*tp_itemsize*/
 /* methods */
 (destructor)DB_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)DB_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
 0, /*tp_compare*/
 0, /*tp_repr*/
 0, /*tp_as_number*/
@@ -6360,58 +6544,82 @@
 0,			/* tp_call */
 0,			/* tp_str */
 0, 		/* tp_getattro */
- 0, /* tp_setattro */
+ 0, /* tp_setattro */
 0,			/* tp_as_buffer */
+#if (PY_VERSION_HEX < 0x03000000)
 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
- 0, /* tp_doc */
- 0,		 /* tp_traverse */
+#else
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+#endif
+ 0, /* tp_doc */
+ 0,		 /* tp_traverse */
 0,			/* tp_clear */
 0,			/* tp_richcompare */
 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ DB_methods, /*tp_methods*/
+ 0, /*tp_members*/
 };
 
 
 statichere PyTypeObject DBCursor_Type = {
+#if (PY_VERSION_HEX < 0x03000000)
 PyObject_HEAD_INIT(NULL)
 0, /*ob_size*/
+#else
+ PyVarObject_HEAD_INIT(NULL, 0)
+#endif
 "DBCursor", /*tp_name*/
 sizeof(DBCursorObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
+ 0, /*tp_itemsize*/
 /* methods */
 (destructor)DBCursor_dealloc,/*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)DBCursor_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0,			/* tp_call */
- 0,			/* tp_str */
- 0, 		/* tp_getattro */
- 0, /* tp_setattro */
- 0,			/* tp_as_buffer */
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+#if (PY_VERSION_HEX < 0x03000000)
 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
- 0, /* tp_doc */
- 0,		 /* tp_traverse */
- 0,			/* tp_clear */
- 0,			/* tp_richcompare */
+#else
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+#endif
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ DBCursor_methods, /*tp_methods*/
+ 0, /*tp_members*/
 };
 
 
 statichere PyTypeObject DBEnv_Type = {
+#if (PY_VERSION_HEX < 0x03000000)
 PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
+ 0, /*ob_size*/
+#else
+ PyVarObject_HEAD_INIT(NULL, 0)
+#endif
 "DBEnv", /*tp_name*/
 sizeof(DBEnvObject), /*tp_basicsize*/
 0, /*tp_itemsize*/
 /* methods */
 (destructor)DBEnv_dealloc, /*tp_dealloc*/
 0, /*tp_print*/
- (getattrfunc)DBEnv_getattr, /*tp_getattr*/
+ 0, /*tp_getattr*/
 0, /*tp_setattr*/
 0, /*tp_compare*/
 0, /*tp_repr*/
@@ -6422,27 +6630,40 @@
 0,			/* tp_call */
 0,			/* tp_str */
 0, 		/* tp_getattro */
- 0, /* tp_setattro */
+ 0, /* tp_setattro */
 0,			/* tp_as_buffer */
+#if (PY_VERSION_HEX < 0x03000000)
 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
- 0, /* tp_doc */
- 0,		 /* tp_traverse */
+#else
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+#endif
+ 0, /* tp_doc */
+ 0,		 /* tp_traverse */
 0,			/* tp_clear */
 0,			/* tp_richcompare */
 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ DBEnv_methods, /* tp_methods */
+ 0, /* tp_members */
+ DBEnv_getsets, /* tp_getsets */
 };
 
 statichere PyTypeObject DBTxn_Type = {
+#if (PY_VERSION_HEX < 0x03000000)
 PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
+ 0, /*ob_size*/
+#else
+ PyVarObject_HEAD_INIT(NULL, 0)
+#endif
 "DBTxn", /*tp_name*/
 sizeof(DBTxnObject), /*tp_basicsize*/
 0, /*tp_itemsize*/
 /* methods */
 (destructor)DBTxn_dealloc, /*tp_dealloc*/
 0, /*tp_print*/
- (getattrfunc)DBTxn_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
 0, /*tp_compare*/
 0, /*tp_repr*/
 0, /*tp_as_number*/
@@ -6452,28 +6673,40 @@
 0,			/* tp_call */
 0,			/* tp_str */
 0, 		/* tp_getattro */
- 0, /* tp_setattro */
+ 0, /* tp_setattro */
 0,			/* tp_as_buffer */
+#if (PY_VERSION_HEX < 0x03000000)
 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
- 0, /* tp_doc */
- 0,		 /* tp_traverse */
+#else
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+#endif
+ 0, /* tp_doc */
+ 0,	 /* tp_traverse */
 0,			/* tp_clear */
 0,			/* tp_richcompare */
 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ DBTxn_methods, /*tp_methods*/
+ 0, /*tp_members*/
 };
 
 
 statichere PyTypeObject DBLock_Type = {
+#if (PY_VERSION_HEX < 0x03000000)
 PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
+ 0, /*ob_size*/
+#else
+ PyVarObject_HEAD_INIT(NULL, 0)
+#endif
 "DBLock", /*tp_name*/
 sizeof(DBLockObject), /*tp_basicsize*/
 0, /*tp_itemsize*/
 /* methods */
 (destructor)DBLock_dealloc, /*tp_dealloc*/
 0, /*tp_print*/
- (getattrfunc)DBLock_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
 0, /*tp_compare*/
 0, /*tp_repr*/
 0, /*tp_as_number*/
@@ -6483,11 +6716,15 @@
 0,			/* tp_call */
 0,			/* tp_str */
 0, 		/* tp_getattro */
- 0, /* tp_setattro */
+ 0, /* tp_setattro */
 0,			/* tp_as_buffer */
+#if (PY_VERSION_HEX < 0x03000000)
 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
- 0, /* tp_doc */
- 0,		 /* tp_traverse */
+#else
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+#endif
+ 0, /* tp_doc */
+ 0,		 /* tp_traverse */
 0,			/* tp_clear */
 0,			/* tp_richcompare */
 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
@@ -6495,15 +6732,19 @@
 
 #if (DBVER >= 43)
 statichere PyTypeObject DBSequence_Type = {
+#if (PY_VERSION_HEX < 0x03000000)
 PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
+ 0, /*ob_size*/
+#else
+ PyVarObject_HEAD_INIT(NULL, 0)
+#endif
 "DBSequence", /*tp_name*/
 sizeof(DBSequenceObject), /*tp_basicsize*/
 0, /*tp_itemsize*/
 /* methods */
 (destructor)DBSequence_dealloc, /*tp_dealloc*/
 0, /*tp_print*/
- (getattrfunc)DBSequence_getattr,/*tp_getattr*/
+ 0, /*tp_getattr*/
 0, /*tp_setattr*/
 0, /*tp_compare*/
 0, /*tp_repr*/
@@ -6516,12 +6757,20 @@
 0, 		/* tp_getattro */
 0, /* tp_setattro */
 0,			/* tp_as_buffer */
+#if (PY_VERSION_HEX < 0x03000000)
 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+#else
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+#endif
 0, /* tp_doc */
 0,		 /* tp_traverse */
 0,			/* tp_clear */
 0,			/* tp_richcompare */
 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ DBSequence_methods, /*tp_methods*/
+ 0, /*tp_members*/
 };
 #endif
 
@@ -6580,29 +6829,27 @@
 underlying DB library.";
 
 static PyObject*
-bsddb_version(PyObject* self, PyObject* args)
+bsddb_version(PyObject* self)
 {
 int major, minor, patch;
 
- if (!PyArg_ParseTuple(args, ":version"))
- return NULL;
- db_version(&major, &minor, &patch);
- return Py_BuildValue("(iii)", major, minor, patch);
+ db_version(&major, &minor, &patch);
+ return Py_BuildValue("(iii)", major, minor, patch);
 }
 
 
 /* List of functions defined in the module */
-
 static PyMethodDef bsddb_methods[] = {
 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
-#if (DBVER >= 43) 
+#if (DBVER >= 43)
 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
-#endif 
- {"version", (PyCFunction)bsddb_version, METH_VARARGS, bsddb_version_doc},
+#endif
+ {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
 {NULL, NULL} /* sentinel */
 };
 
+
 /* API structure */
 static BSDDB_api bsddb_api;
 
@@ -6619,7 +6866,27 @@
 #define MODULE_NAME_MAX_LEN 11
 static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
 
+#if (PY_VERSION_HEX >= 0x03000000)
+static struct PyModuleDef bsddbmodule = {
+ PyModuleDef_HEAD_INIT,
+ _bsddbModuleName, /* Name of module */
+ NULL, /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module,
+ or -1 if the module keeps state in global variables. */
+ bsddb_methods,
+ NULL, /* Reload */
+ NULL, /* Traverse */
+ NULL, /* Clear */
+ NULL /* Free */
+};
+#endif
+
+
+#if (PY_VERSION_HEX < 0x03000000)
 DL_EXPORT(void) init_bsddb(void)
+#else
+PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
+#endif
 {
 PyObject* m;
 PyObject* d;
@@ -6628,17 +6895,22 @@
 PyObject* cvsid_s = PyBytes_FromString( rcs_id );
 PyObject* py_api;
 
- /* Initialize the type of the new type objects here; doing it here
- is required for portability to Windows without requiring C++. */
- Py_TYPE(&DB_Type) = &PyType_Type;
- Py_TYPE(&DBCursor_Type) = &PyType_Type;
- Py_TYPE(&DBEnv_Type) = &PyType_Type;
- Py_TYPE(&DBTxn_Type) = &PyType_Type;
- Py_TYPE(&DBLock_Type) = &PyType_Type;
-#if (DBVER >= 43) 
- Py_TYPE(&DBSequence_Type) = &PyType_Type;
-#endif 
-
+ /* Initialize object types */
+ if ((PyType_Ready(&DB_Type) < 0)
+ || (PyType_Ready(&DBCursor_Type) < 0)
+ || (PyType_Ready(&DBEnv_Type) < 0)
+ || (PyType_Ready(&DBTxn_Type) < 0)
+ || (PyType_Ready(&DBLock_Type) < 0)
+#if (DBVER >= 43)
+ || (PyType_Ready(&DBSequence_Type) < 0)
+#endif
+ ) {
+#if (PY_VERSION_HEX < 0x03000000)
+ return;
+#else
+ return NULL;
+#endif
+ }
 
 #if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
 /* Save the current interpreter, so callbacks can do the right thing. */
@@ -6646,9 +6918,18 @@
 #endif
 
 /* Create the module and add the functions */
+#if (PY_VERSION_HEX < 0x03000000)
 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
- if (m == NULL)
- 	return;
+#else
+ m=PyModule_Create(&bsddbmodule);
+#endif
+ if (m == NULL) {
+#if (PY_VERSION_HEX < 0x03000000)
+ return;
+#else
+ 	return NULL;
+#endif
+ }
 
 /* Add some symbolic constants to the module */
 d = PyModule_GetDict(m);
@@ -6693,9 +6974,7 @@
 ADD_INT(d, DB_INIT_TXN);
 ADD_INT(d, DB_JOINENV);
 
-#if (DBVER >= 40)
 ADD_INT(d, DB_XIDDATASIZE);
-#endif
 
 ADD_INT(d, DB_RECOVER);
 ADD_INT(d, DB_RECOVER_FATAL);
@@ -6725,10 +7004,7 @@
 ADD_INT(d, DB_NOORDERCHK);
 ADD_INT(d, DB_ORDERCHKONLY);
 ADD_INT(d, DB_PR_PAGE);
-#if ! (DBVER >= 33)
- ADD_INT(d, DB_VRFY_FLAGMASK);
- ADD_INT(d, DB_PR_HEADERS);
-#endif
+
 ADD_INT(d, DB_PR_RECOVERYTEST);
 ADD_INT(d, DB_SALVAGE);
 
@@ -6737,26 +7013,16 @@
 ADD_INT(d, DB_LOCK_OLDEST);
 ADD_INT(d, DB_LOCK_RANDOM);
 ADD_INT(d, DB_LOCK_YOUNGEST);
-#if (DBVER >= 33)
 ADD_INT(d, DB_LOCK_MAXLOCKS);
 ADD_INT(d, DB_LOCK_MINLOCKS);
 ADD_INT(d, DB_LOCK_MINWRITE);
-#endif
 
-#if (DBVER >= 40)
 ADD_INT(d, DB_LOCK_EXPIRE);
-#endif
 #if (DBVER >= 43)
 ADD_INT(d, DB_LOCK_MAXWRITE);
 #endif
 
-
-#if (DBVER >= 33)
- /* docs say to use zero instead */
 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
-#else
- ADD_INT(d, DB_LOCK_CONFLICT);
-#endif
 
 ADD_INT(d, DB_LOCK_DUMP);
 ADD_INT(d, DB_LOCK_GET);
@@ -6773,39 +7039,31 @@
 ADD_INT(d, DB_LOCK_IWRITE);
 ADD_INT(d, DB_LOCK_IREAD);
 ADD_INT(d, DB_LOCK_IWR);
-#if (DBVER >= 33)
 #if (DBVER < 44)
 ADD_INT(d, DB_LOCK_DIRTY);
 #else
 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
 #endif
 ADD_INT(d, DB_LOCK_WWRITE);
-#endif
 
 ADD_INT(d, DB_LOCK_RECORD);
 ADD_INT(d, DB_LOCK_UPGRADE);
 ADD_INT(d, DB_LOCK_SWITCH);
-#if (DBVER >= 33)
 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
-#endif
 
 ADD_INT(d, DB_LOCK_NOWAIT);
 ADD_INT(d, DB_LOCK_RECORD);
 ADD_INT(d, DB_LOCK_UPGRADE);
 
-#if (DBVER >= 33)
 ADD_INT(d, DB_LSTAT_ABORTED);
 #if (DBVER < 43)
 ADD_INT(d, DB_LSTAT_ERR);
 #endif
 ADD_INT(d, DB_LSTAT_FREE);
 ADD_INT(d, DB_LSTAT_HELD);
-#if (DBVER == 33)
- ADD_INT(d, DB_LSTAT_NOGRANT);
-#endif
+
 ADD_INT(d, DB_LSTAT_PENDING);
 ADD_INT(d, DB_LSTAT_WAITING);
-#endif
 
 ADD_INT(d, DB_ARCH_ABS);
 ADD_INT(d, DB_ARCH_DATA);
@@ -6842,15 +7100,13 @@
 ADD_INT(d, DB_CHECKPOINT);
 ADD_INT(d, DB_CURLSN);
 #endif
-#if ((DBVER >= 33) && (DBVER <= 41))
+#if (DBVER <= 41)
 ADD_INT(d, DB_COMMIT);
 #endif
 ADD_INT(d, DB_CONSUME);
 ADD_INT(d, DB_CONSUME_WAIT);
 ADD_INT(d, DB_CURRENT);
-#if (DBVER >= 33)
 ADD_INT(d, DB_FAST_STAT);
-#endif
 ADD_INT(d, DB_FIRST);
 ADD_INT(d, DB_FLUSH);
 ADD_INT(d, DB_GET_BOTH);
@@ -6878,20 +7134,16 @@
 
 ADD_INT(d, DB_OPFLAGS_MASK);
 ADD_INT(d, DB_RMW);
-#if (DBVER >= 33)
 ADD_INT(d, DB_DIRTY_READ);
 ADD_INT(d, DB_MULTIPLE);
 ADD_INT(d, DB_MULTIPLE_KEY);
-#endif
 
 #if (DBVER >= 44)
 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
 ADD_INT(d, DB_READ_COMMITTED);
 #endif
 
-#if (DBVER >= 33)
 ADD_INT(d, DB_DONOTINDEX);
-#endif
 
 #if (DBVER >= 41)
 _addIntToDict(d, "DB_INCOMPLETE", 0);
@@ -6909,18 +7161,14 @@
 ADD_INT(d, DB_OLD_VERSION);
 ADD_INT(d, DB_RUNRECOVERY);
 ADD_INT(d, DB_VERIFY_BAD);
-#if (DBVER >= 33)
 ADD_INT(d, DB_PAGE_NOTFOUND);
 ADD_INT(d, DB_SECONDARY_BAD);
-#endif
-#if (DBVER >= 40)
 ADD_INT(d, DB_STAT_CLEAR);
 ADD_INT(d, DB_REGION_INIT);
 ADD_INT(d, DB_NOLOCKING);
 ADD_INT(d, DB_YIELDCPU);
 ADD_INT(d, DB_PANIC_ENVIRONMENT);
 ADD_INT(d, DB_NOPANIC);
-#endif
 
 #if (DBVER >= 41)
 ADD_INT(d, DB_OVERWRITE);
@@ -6961,7 +7209,6 @@
 ADD_INT(d, DB_TXN_SNAPSHOT);
 #endif
 
-#if (DBVER >= 40)
 ADD_INT(d, DB_VERB_DEADLOCK);
 #if (DBVER >= 46)
 ADD_INT(d, DB_VERB_FILEOPS);
@@ -6973,7 +7220,6 @@
 #endif
 ADD_INT(d, DB_VERB_REPLICATION);
 ADD_INT(d, DB_VERB_WAITSFOR);
-#endif
 
 #if (DBVER >= 45)
 ADD_INT(d, DB_EVENT_PANIC);
@@ -6990,7 +7236,18 @@
 ADD_INT(d, DB_EVENT_WRITE_FAILED);
 #endif
 
-#if (DBVER >= 40)
+ ADD_INT(d, DB_REP_DUPMASTER);
+ ADD_INT(d, DB_REP_HOLDELECTION);
+#if (DBVER >= 44)
+ ADD_INT(d, DB_REP_IGNORE);
+ ADD_INT(d, DB_REP_JOIN_FAILURE);
+#endif
+#if (DBVER >= 42)
+ ADD_INT(d, DB_REP_ISPERM);
+ ADD_INT(d, DB_REP_NOTPERM);
+#endif
+ ADD_INT(d, DB_REP_NEWSITE);
+
 ADD_INT(d, DB_REP_MASTER);
 ADD_INT(d, DB_REP_CLIENT);
 #if (DBVER >= 45)
@@ -7005,7 +7262,6 @@
 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
 #endif
-#endif
 
 #if (DBVER >= 45)
 ADD_INT(d, DB_REPMGR_PEER);
@@ -7051,10 +7307,8 @@
 ADD_INT(d, ENOENT);
 ADD_INT(d, EPERM);
 
-#if (DBVER >= 40)
 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
 ADD_INT(d, DB_SET_TXN_TIMEOUT);
-#endif
 
 /* The exception name must be correct for pickled exception *
 * objects to unpickle properly. */
@@ -7072,6 +7326,7 @@
 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
 MAKE_EX(DBError);
 
+#if (PY_VERSION_HEX < 0x03000000)
 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
 * from both DBError and KeyError, since the API only supports
 * using one base class. */
@@ -7082,6 +7337,26 @@
 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
 PyDict_DelItemString(d, "KeyError");
+#else
+ /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
+ ** derive from several classes. We use this new API only for Python 3.0,
+ ** though.
+ */
+ {
+ PyObject* bases;
+
+ bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
+
+#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
+ PyDict_SetItemString(d, #name, name)
+ MAKE_EX2(DBNotFoundError);
+ MAKE_EX2(DBKeyEmptyError);
+
+#undef MAKE_EX2
+
+ Py_XDECREF(bases);
+ }
+#endif
 
 
 #if !INCOMPLETE_IS_WARNING
@@ -7098,10 +7373,8 @@
 MAKE_EX(DBNoServerError);
 MAKE_EX(DBNoServerHomeError);
 MAKE_EX(DBNoServerIDError);
-#if (DBVER >= 33)
 MAKE_EX(DBPageNotFoundError);
 MAKE_EX(DBSecondaryBadError);
-#endif
 
 MAKE_EX(DBInvalidArgError);
 MAKE_EX(DBAccessError);
@@ -7117,6 +7390,8 @@
 MAKE_EX(DBRepHandleDeadError);
 #endif
 
+ MAKE_EX(DBRepUnavailError);
+
 #undef MAKE_EX
 
 /* Initiliase the C API structure and add it to the module */
@@ -7137,15 +7412,31 @@
 /* Check for errors */
 if (PyErr_Occurred()) {
 PyErr_Print();
- Py_FatalError("can't initialize module _bsddb");
+ Py_FatalError("can't initialize module _bsddb/_pybsddb");
+ Py_DECREF(m);
+ m = NULL;
 }
+#if (PY_VERSION_HEX < 0x03000000)
+ return;
+#else
+ return m;
+#endif
 }
 
 /* allow this module to be named _pybsddb so that it can be installed
 * and imported on top of python >= 2.3 that includes its own older
 * copy of the library named _bsddb without importing the old version. */
+#if (PY_VERSION_HEX < 0x03000000)
 DL_EXPORT(void) init_pybsddb(void)
+#else
+PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
+#endif
 {
 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
+#if (PY_VERSION_HEX < 0x03000000)
 init_bsddb();
+#else
+ return PyInit__bsddb(); /* Note the two underscores */
+#endif
 }
+
Modified: python/trunk/Modules/bsddb.h
==============================================================================
--- python/trunk/Modules/bsddb.h	(original)
+++ python/trunk/Modules/bsddb.h	Wed Jul 23 13:38:42 2008
@@ -105,7 +105,7 @@
 #error "eek! DBVER can't handle minor versions > 9"
 #endif
 
-#define PY_BSDDB_VERSION "4.7.0"
+#define PY_BSDDB_VERSION "4.7.2devel9"
 
 /* Python object definitions */
 
@@ -131,11 +131,11 @@
 u_int32_t flags; /* saved flags from open() */
 int closed;
 struct behaviourFlags moduleFlags;
-#if (DBVER >= 40)
 PyObject* event_notifyCallback;
-#endif
 struct DBObject *children_dbs;
 struct DBTxnObject *children_txns;
+ PyObject *private;
+ PyObject *rep_transport;
 PyObject *in_weakreflist; /* List of weak references */
 } DBEnvObject;
 
@@ -156,11 +156,10 @@
 struct DBObject *sibling_next;
 struct DBObject **sibling_prev_p_txn;
 struct DBObject *sibling_next_txn;
-#if (DBVER >= 33)
 PyObject* associateCallback;
 PyObject* btCompareCallback;
 int primaryDBType;
-#endif
+ PyObject *private;
 PyObject *in_weakreflist; /* List of weak references */
 } DBObject;
 


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /