[Python-checkins] r66088 - in python/trunk: 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_compat.py Lib/bsddb/test/test_cursor_pget_bug.py Lib/bsddb/test/test_dbobj.py Lib/bsddb/test/test_dbshelve.py Lib/bsddb/test/test_dbtables.py Lib/bsddb/test/test_distributed_transactions.py Lib/bsddb/test/test_early_close.py Lib/bsddb/test/test_get_none.py Lib/bsddb/test/test_join.py Lib/bsddb/test/test_lock.py Lib/bsddb/test/test_misc.py Lib/bsddb/test/test_pickle.py Lib/bsddb/test/test_queue.py Lib/bsddb/test/test_recno.py Lib/bsddb/test/test_replication.py Lib/bsddb/test/test_sequence.py Lib/bsddb/test/test_thread.py Misc/NEWS Modules/_bsddb.c Modules/bsddb.h

jesus.cea python-checkins at python.org
Sun Aug 31 16:00:52 CEST 2008


Author: jesus.cea
Date: Sun Aug 31 16:00:51 2008
New Revision: 66088

Log:
Update bsddb code to version 4.7.3pre2. This code should
be compatible with Python 3.0, also.

  http://www.jcea.es/programacion/pybsddb.htm#bsddb3-4.7.3



Modified:
   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_compat.py
   python/trunk/Lib/bsddb/test/test_cursor_pget_bug.py
   python/trunk/Lib/bsddb/test/test_dbobj.py
   python/trunk/Lib/bsddb/test/test_dbshelve.py
   python/trunk/Lib/bsddb/test/test_dbtables.py
   python/trunk/Lib/bsddb/test/test_distributed_transactions.py
   python/trunk/Lib/bsddb/test/test_early_close.py
   python/trunk/Lib/bsddb/test/test_get_none.py
   python/trunk/Lib/bsddb/test/test_join.py
   python/trunk/Lib/bsddb/test/test_lock.py
   python/trunk/Lib/bsddb/test/test_misc.py
   python/trunk/Lib/bsddb/test/test_pickle.py
   python/trunk/Lib/bsddb/test/test_queue.py
   python/trunk/Lib/bsddb/test/test_recno.py
   python/trunk/Lib/bsddb/test/test_replication.py
   python/trunk/Lib/bsddb/test/test_sequence.py
   python/trunk/Lib/bsddb/test/test_thread.py
   python/trunk/Misc/NEWS
   python/trunk/Modules/_bsddb.c
   python/trunk/Modules/bsddb.h

Modified: python/trunk/Lib/bsddb/dbshelve.py
==============================================================================
--- python/trunk/Lib/bsddb/dbshelve.py	(original)
+++ python/trunk/Lib/bsddb/dbshelve.py	Sun Aug 31 16:00:51 2008
@@ -218,8 +218,13 @@
 
     def associate(self, secondaryDB, callback, flags=0):
         def _shelf_callback(priKey, priData, realCallback=callback):
-            data = cPickle.loads(priData)
+            # Safe in Python 2.x because expresion short circuit
+            if sys.version_info[0] < 3 or isinstance(priData, bytes) :
+                data = cPickle.loads(priData)
+            else :
+                data = cPickle.loads(bytes(priData, "iso8859-1"))  # 8 bits
             return realCallback(priKey, data)
+
         return self.db.associate(secondaryDB, _shelf_callback, flags)
 
 
@@ -232,7 +237,7 @@
         data = apply(self.db.get, args, kw)
         try:
             return cPickle.loads(data)
-        except (TypeError, cPickle.UnpicklingError):
+        except (EOFError, TypeError, cPickle.UnpicklingError):
             return data  # we may be getting the default value, or None,
                          # so it doesn't need unpickled.
 
@@ -350,7 +355,11 @@
             return None
         else:
             key, data = rec
-            return key, cPickle.loads(data)
+            # Safe in Python 2.x because expresion short circuit
+            if sys.version_info[0] < 3 or isinstance(data, bytes) :
+                return key, cPickle.loads(data)
+            else :
+                return key, cPickle.loads(bytes(data, "iso8859-1"))  # 8 bits
 
     #----------------------------------------------
     # Methods allowed to pass-through to self.dbc

Modified: python/trunk/Lib/bsddb/dbtables.py
==============================================================================
--- python/trunk/Lib/bsddb/dbtables.py	(original)
+++ python/trunk/Lib/bsddb/dbtables.py	Sun Aug 31 16:00:51 2008
@@ -26,17 +26,16 @@
 
 try:
     # For Pythons w/distutils pybsddb
-    from bsddb3.db import *
+    from bsddb3 import db
 except ImportError:
     # For Python 2.3
-    from bsddb.db import *
+    from bsddb import db
 
 # XXX(nnorwitz): is this correct? DBIncompleteError is conditional in _bsddb.c
-try:
-    DBIncompleteError
-except NameError:
+if not hasattr(db,"DBIncompleteError") :
     class DBIncompleteError(Exception):
         pass
+    db.DBIncompleteError = DBIncompleteError
 
 class TableDBError(StandardError):
     pass
@@ -104,6 +103,7 @@
                      # row in the table.  (no data is stored)
 _rowid_str_len = 8   # length in bytes of the unique rowid strings
 
+
 def _data_key(table, col, rowid):
     return table + _data + col + _data + rowid
 
@@ -142,37 +142,104 @@
         Use keyword arguments when calling this constructor.
         """
         self.db = None
-        myflags = DB_THREAD
+        myflags = db.DB_THREAD
         if create:
-            myflags |= DB_CREATE
-        flagsforenv = (DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_LOG |
-                       DB_INIT_TXN | dbflags)
+            myflags |= db.DB_CREATE
+        flagsforenv = (db.DB_INIT_MPOOL | db.DB_INIT_LOCK | db.DB_INIT_LOG |
+                       db.DB_INIT_TXN | dbflags)
         # DB_AUTO_COMMIT isn't a valid flag for env.open()
         try:
-            dbflags |= DB_AUTO_COMMIT
+            dbflags |= db.DB_AUTO_COMMIT
         except AttributeError:
             pass
         if recover:
-            flagsforenv = flagsforenv | DB_RECOVER
-        self.env = DBEnv()
+            flagsforenv = flagsforenv | db.DB_RECOVER
+        self.env = db.DBEnv()
         # enable auto deadlock avoidance
-        self.env.set_lk_detect(DB_LOCK_DEFAULT)
+        self.env.set_lk_detect(db.DB_LOCK_DEFAULT)
         self.env.open(dbhome, myflags | flagsforenv)
         if truncate:
-            myflags |= DB_TRUNCATE
-        self.db = DB(self.env)
+            myflags |= db.DB_TRUNCATE
+        self.db = db.DB(self.env)
         # this code relies on DBCursor.set* methods to raise exceptions
         # rather than returning None
         self.db.set_get_returns_none(1)
         # allow duplicate entries [warning: be careful w/ metadata]
-        self.db.set_flags(DB_DUP)
-        self.db.open(filename, DB_BTREE, dbflags | myflags, mode)
+        self.db.set_flags(db.DB_DUP)
+        self.db.open(filename, db.DB_BTREE, dbflags | myflags, mode)
         self.dbfilename = filename
+
+        if sys.version_info[0] >= 3 :
+            class cursor_py3k(object) :
+                def __init__(self, dbcursor) :
+                    self._dbcursor = dbcursor
+
+                def close(self) :
+                    return self._dbcursor.close()
+
+                def set_range(self, search) :
+                    v = self._dbcursor.set_range(bytes(search, "iso8859-1"))
+                    if v != None :
+                        v = (v[0].decode("iso8859-1"),
+                                v[1].decode("iso8859-1"))
+                    return v
+
+                def __next__(self) :
+                    v = getattr(self._dbcursor, "next")()
+                    if v != None :
+                        v = (v[0].decode("iso8859-1"),
+                                v[1].decode("iso8859-1"))
+                    return v
+
+            class db_py3k(object) :
+                def __init__(self, db) :
+                    self._db = db
+
+                def cursor(self, txn=None) :
+                    return cursor_py3k(self._db.cursor(txn=txn))
+
+                def has_key(self, key, txn=None) :
+                    return getattr(self._db,"has_key")(bytes(key, "iso8859-1"),
+                            txn=txn)
+
+                def put(self, key, value, flags=0, txn=None) :
+                    key = bytes(key, "iso8859-1")
+                    if value != None :
+                        value = bytes(value, "iso8859-1")
+                    return self._db.put(key, value, flags=flags, txn=txn)
+
+                def put_bytes(self, key, value, txn=None) :
+                    key = bytes(key, "iso8859-1")
+                    return self._db.put(key, value, txn=txn)
+
+                def get(self, key, txn=None, flags=0) :
+                    key = bytes(key, "iso8859-1")
+                    v = self._db.get(key, txn=txn, flags=flags)
+                    if v != None :
+                        v = v.decode("iso8859-1")
+                    return v
+
+                def get_bytes(self, key, txn=None, flags=0) :
+                    key = bytes(key, "iso8859-1")
+                    return self._db.get(key, txn=txn, flags=flags)
+
+                def delete(self, key, txn=None) :
+                    key = bytes(key, "iso8859-1")
+                    return self._db.delete(key, txn=txn)
+
+                def close (self) :
+                    return self._db.close()
+
+            self.db = db_py3k(self.db)
+        else :  # Python 2.x
+            pass
+
         # Initialize the table names list if this is a new database
         txn = self.env.txn_begin()
         try:
-            if not self.db.has_key(_table_names_key, txn):
-                self.db.put(_table_names_key, pickle.dumps([], 1), txn=txn)
+            if not getattr(self.db, "has_key")(_table_names_key, txn):
+                getattr(self.db, "put_bytes", self.db.put) \
+                        (_table_names_key, pickle.dumps([], 1), txn=txn)
         # Yes, bare except
         except:
             txn.abort()
@@ -196,13 +263,13 @@
     def checkpoint(self, mins=0):
         try:
             self.env.txn_checkpoint(mins)
-        except DBIncompleteError:
+        except db.DBIncompleteError:
             pass
 
     def sync(self):
         try:
             self.db.sync()
-        except DBIncompleteError:
+        except db.DBIncompleteError:
             pass
 
     def _db_print(self) :
@@ -219,7 +286,7 @@
                 else:
                     cur.close()
                     return
-        except DBNotFoundError:
+        except db.DBNotFoundError:
             cur.close()
 
 
@@ -229,6 +296,7 @@
         raises TableDBError if it already exists or for other DB errors.
         """
         assert isinstance(columns, list)
+
         txn = None
         try:
             # checking sanity of the table and column names here on
@@ -242,27 +310,32 @@
                         "bad column name: contains reserved metastrings")
 
             columnlist_key = _columns_key(table)
-            if self.db.has_key(columnlist_key):
+            if getattr(self.db, "has_key")(columnlist_key):
                 raise TableAlreadyExists, "table already exists"
 
             txn = self.env.txn_begin()
             # store the table's column info
-            self.db.put(columnlist_key, pickle.dumps(columns, 1), txn=txn)
+            getattr(self.db, "put_bytes", self.db.put)(columnlist_key,
+                    pickle.dumps(columns, 1), txn=txn)
 
             # add the table name to the tablelist
-            tablelist = pickle.loads(self.db.get(_table_names_key, txn=txn,
-                                                 flags=DB_RMW))
+            tablelist = pickle.loads(getattr(self.db, "get_bytes",
+                self.db.get) (_table_names_key, txn=txn, flags=db.DB_RMW))
             tablelist.append(table)
             # delete 1st, in case we opened with DB_DUP
             self.db.delete(_table_names_key, txn=txn)
-            self.db.put(_table_names_key, pickle.dumps(tablelist, 1), txn=txn)
+            getattr(self.db, "put_bytes", self.db.put)(_table_names_key,
+                    pickle.dumps(tablelist, 1), txn=txn)
 
             txn.commit()
             txn = None
-        except DBError, dberror:
+        except db.DBError, dberror:
             if txn:
                 txn.abort()
-            raise TableDBError, dberror[1]
+            if sys.version_info[0] < 3 :
+                raise TableDBError, dberror[1]
+            else :
+                raise TableDBError, dberror.args[1]
 
 
     def ListTableColumns(self, table):
@@ -274,9 +347,10 @@
             raise ValueError, "bad table name: contains reserved metastrings"
 
         columnlist_key = _columns_key(table)
-        if not self.db.has_key(columnlist_key):
+        if not getattr(self.db, "has_key")(columnlist_key):
             return []
-        pickledcolumnlist = self.db.get(columnlist_key)
+        pickledcolumnlist = getattr(self.db, "get_bytes",
+                self.db.get)(columnlist_key)
         if pickledcolumnlist:
             return pickle.loads(pickledcolumnlist)
         else:
@@ -284,7 +358,7 @@
 
     def ListTables(self):
         """Return a list of tables in this database."""
-        pickledtablelist = self.db.get(_table_names_key)
+        pickledtablelist = self.db.get_get(_table_names_key)
         if pickledtablelist:
             return pickle.loads(pickledtablelist)
         else:
@@ -300,6 +374,7 @@
         all of its current columns.
         """
         assert isinstance(columns, list)
+
         try:
             self.CreateTable(table, columns)
         except TableAlreadyExists:
@@ -311,7 +386,8 @@
 
                 # load the current column list
                 oldcolumnlist = pickle.loads(
-                    self.db.get(columnlist_key, txn=txn, flags=DB_RMW))
+                    getattr(self.db, "get_bytes",
+                        self.db.get)(columnlist_key, txn=txn, flags=db.DB_RMW))
                 # create a hash table for fast lookups of column names in the
                 # loop below
                 oldcolumnhash = {}
@@ -329,7 +405,7 @@
                 if newcolumnlist != oldcolumnlist :
                     # delete the old one first since we opened with DB_DUP
                     self.db.delete(columnlist_key, txn=txn)
-                    self.db.put(columnlist_key,
+                    getattr(self.db, "put_bytes", self.db.put)(columnlist_key,
                                 pickle.dumps(newcolumnlist, 1),
                                 txn=txn)
 
@@ -337,18 +413,22 @@
                 txn = None
 
                 self.__load_column_info(table)
-            except DBError, dberror:
+            except db.DBError, dberror:
                 if txn:
                     txn.abort()
-                raise TableDBError, dberror[1]
+                if sys.version_info[0] < 3 :
+                    raise TableDBError, dberror[1]
+                else :
+                    raise TableDBError, dberror.args[1]
 
 
     def __load_column_info(self, table) :
         """initialize the self.__tablecolumns dict"""
         # check the column names
         try:
-            tcolpickles = self.db.get(_columns_key(table))
-        except DBNotFoundError:
+            tcolpickles = getattr(self.db, "get_bytes",
+                    self.db.get)(_columns_key(table))
+        except db.DBNotFoundError:
             raise TableDBError, "unknown table: %r" % (table,)
         if not tcolpickles:
             raise TableDBError, "unknown table: %r" % (table,)
@@ -366,11 +446,14 @@
                 blist.append(random.randint(0,255))
             newid = struct.pack('B'*_rowid_str_len, *blist)
 
+            if sys.version_info[0] >= 3 :
+                newid = newid.decode("iso8859-1")  # 8 bits
+
             # Guarantee uniqueness by adding this key to the database
             try:
                 self.db.put(_rowid_key(table, newid), None, txn=txn,
-                            flags=DB_NOOVERWRITE)
-            except DBKeyExistError:
+                            flags=db.DB_NOOVERWRITE)
+            except db.DBKeyExistError:
                 pass
             else:
                 unique = 1
@@ -382,9 +465,10 @@
         """Insert(table, datadict) - Insert a new row into the table
         using the keys+values from rowdict as the column values.
         """
+
         txn = None
         try:
-            if not self.db.has_key(_columns_key(table)):
+            if not getattr(self.db, "has_key")(_columns_key(table)):
                 raise TableDBError, "unknown table"
 
             # check the validity of each column name
@@ -406,7 +490,7 @@
             txn.commit()
             txn = None
 
-        except DBError, dberror:
+        except db.DBError, dberror:
             # WIBNI we could just abort the txn and re-raise the exception?
             # But no, because TableDBError is not related to DBError via
             # inheritance, so it would be backwards incompatible.  Do the next
@@ -415,7 +499,10 @@
             if txn:
                 txn.abort()
                 self.db.delete(_rowid_key(table, rowid))
-            raise TableDBError, dberror[1], info[2]
+            if sys.version_info[0] < 3 :
+                raise TableDBError, dberror[1], info[2]
+            else :
+                raise TableDBError, dberror.args[1], info[2]
 
 
     def Modify(self, table, conditions={}, mappings={}):
@@ -429,6 +516,7 @@
           condition callable expecting the data string as an argument and
           returning the new string for that column.
         """
+
         try:
             matching_rowids = self.__Select(table, [], conditions)
 
@@ -447,7 +535,7 @@
                             self.db.delete(
                                 _data_key(table, column, rowid),
                                 txn=txn)
-                        except DBNotFoundError:
+                        except db.DBNotFoundError:
                              # XXXXXXX row key somehow didn't exist, assume no
                              # error
                             dataitem = None
@@ -465,8 +553,11 @@
                         txn.abort()
                     raise
 
-        except DBError, dberror:
-            raise TableDBError, dberror[1]
+        except db.DBError, dberror:
+            if sys.version_info[0] < 3 :
+                raise TableDBError, dberror[1]
+            else :
+                raise TableDBError, dberror.args[1]
 
     def Delete(self, table, conditions={}):
         """Delete(table, conditions) - Delete items matching the given
@@ -476,6 +567,7 @@
           condition functions expecting the data string as an
           argument and returning a boolean.
         """
+
         try:
             matching_rowids = self.__Select(table, [], conditions)
 
@@ -490,23 +582,26 @@
                         try:
                             self.db.delete(_data_key(table, column, rowid),
                                            txn=txn)
-                        except DBNotFoundError:
+                        except db.DBNotFoundError:
                             # XXXXXXX column may not exist, assume no error
                             pass
 
                     try:
                         self.db.delete(_rowid_key(table, rowid), txn=txn)
-                    except DBNotFoundError:
+                    except db.DBNotFoundError:
                         # XXXXXXX row key somehow didn't exist, assume no error
                         pass
                     txn.commit()
                     txn = None
-                except DBError, dberror:
+                except db.DBError, dberror:
                     if txn:
                         txn.abort()
                     raise
-        except DBError, dberror:
-            raise TableDBError, dberror[1]
+        except db.DBError, dberror:
+            if sys.version_info[0] < 3 :
+                raise TableDBError, dberror[1]
+            else :
+                raise TableDBError, dberror.args[1]
 
 
     def Select(self, table, columns, conditions={}):
@@ -525,8 +620,11 @@
             if columns is None:
                 columns = self.__tablecolumns[table]
             matching_rowids = self.__Select(table, columns, conditions)
-        except DBError, dberror:
-            raise TableDBError, dberror[1]
+        except db.DBError, dberror:
+            if sys.version_info[0] < 3 :
+                raise TableDBError, dberror[1]
+            else :
+                raise TableDBError, dberror.args[1]
         # return the matches as a list of dictionaries
         return matching_rowids.values()
 
@@ -579,8 +677,19 @@
             # leave all unknown condition callables alone as equals
             return 0
 
-        conditionlist = conditions.items()
-        conditionlist.sort(cmp_conditions)
+        if sys.version_info[0] < 3 :
+            conditionlist = conditions.items()
+            conditionlist.sort(cmp_conditions)
+        else :  # Insertion Sort. Please, improve
+            conditionlist = []
+            for i in conditions.items() :
+                for j, k in enumerate(conditionlist) :
+                    r = cmp_conditions(k, i)
+                    if r == 1 :
+                        conditionlist.insert(j, i)
+                        break
+                else :
+                    conditionlist.append(i)
 
         # Apply conditions to column data to find what we want
         cur = self.db.cursor()
@@ -615,9 +724,13 @@
 
                     key, data = cur.next()
 
-            except DBError, dberror:
-                if dberror[0] != DB_NOTFOUND:
-                    raise
+            except db.DBError, dberror:
+                if sys.version_info[0] < 3 :
+                    if dberror[0] != db.DB_NOTFOUND:
+                        raise
+                else :
+                    if dberror.args[0] != db.DB_NOTFOUND:
+                        raise
                 continue
 
         cur.close()
@@ -635,9 +748,13 @@
                     try:
                         rowdata[column] = self.db.get(
                             _data_key(table, column, rowid))
-                    except DBError, dberror:
-                        if dberror[0] != DB_NOTFOUND:
-                            raise
+                    except db.DBError, dberror:
+                        if sys.version_info[0] < 3 :
+                            if dberror[0] != db.DB_NOTFOUND:
+                                raise
+                        else :
+                            if dberror.args[0] != db.DB_NOTFOUND:
+                                raise
                         rowdata[column] = None
 
         # return the matches
@@ -660,7 +777,7 @@
             while 1:
                 try:
                     key, data = cur.set_range(table_key)
-                except DBNotFoundError:
+                except db.DBNotFoundError:
                     break
                 # only delete items in this table
                 if key[:len(table_key)] != table_key:
@@ -672,7 +789,7 @@
             while 1:
                 try:
                     key, data = cur.set_range(table_key)
-                except DBNotFoundError:
+                except db.DBNotFoundError:
                     break
                 # only delete items in this table
                 if key[:len(table_key)] != table_key:
@@ -683,7 +800,8 @@
 
             # delete the tablename from the table name list
             tablelist = pickle.loads(
-                self.db.get(_table_names_key, txn=txn, flags=DB_RMW))
+                getattr(self.db, "get_bytes", self.db.get)(_table_names_key,
+                    txn=txn, flags=db.DB_RMW))
             try:
                 tablelist.remove(table)
             except ValueError:
@@ -691,7 +809,8 @@
                 pass
             # delete 1st, incase we opened with DB_DUP
             self.db.delete(_table_names_key, txn=txn)
-            self.db.put(_table_names_key, pickle.dumps(tablelist, 1), txn=txn)
+            getattr(self.db, "put_bytes", self.db.put)(_table_names_key,
+                    pickle.dumps(tablelist, 1), txn=txn)
 
             txn.commit()
             txn = None
@@ -699,7 +818,10 @@
             if self.__tablecolumns.has_key(table):
                 del self.__tablecolumns[table]
 
-        except DBError, dberror:
+        except db.DBError, dberror:
             if txn:
                 txn.abort()
-            raise TableDBError, dberror[1]
+            if sys.version_info[0] < 3 :
+                raise TableDBError, dberror[1]
+            else :
+                raise TableDBError, dberror.args[1]

Modified: python/trunk/Lib/bsddb/dbutils.py
==============================================================================
--- python/trunk/Lib/bsddb/dbutils.py	(original)
+++ python/trunk/Lib/bsddb/dbutils.py	Sun Aug 31 16:00:51 2008
@@ -61,7 +61,7 @@
     """
     sleeptime = _deadlock_MinSleepTime
     max_retries = _kwargs.get('max_retries', -1)
-    if 'max_retries' in _kwargs:
+    if _kwargs.has_key('max_retries'):
         del _kwargs['max_retries']
     while True:
         try:

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	Sun Aug 31 16:00:51 2008
@@ -6,21 +6,366 @@
 import unittest
 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
 
+
+if sys.version_info[0] >= 3 :
+    charset = "iso8859-1"  # Full 8 bit
+
+    class cursor_py3k(object) :
+        def __init__(self, db, *args, **kwargs) :
+            self._dbcursor = db.cursor(*args, **kwargs)
+
+        def __getattr__(self, v) :
+            return getattr(self._dbcursor, v)
+
+        def _fix(self, v) :
+            if v == None : return None
+            key, value = v
+            if isinstance(key, bytes) :
+                key = key.decode(charset)
+            return (key, value.decode(charset))
+
+        def __next__(self) :
+            v = getattr(self._dbcursor, "next")()
+            return self._fix(v)
+
+        def previous(self) :
+            v = self._dbcursor.previous()
+            return self._fix(v)
+
+        def last(self) :
+            v = self._dbcursor.last()
+            return self._fix(v)
+
+        def set(self, k) :
+            if isinstance(k, str) :
+                k = bytes(k, charset)
+            v = self._dbcursor.set(k)
+            return self._fix(v)
+
+        def set_recno(self, num) :
+            v = self._dbcursor.set_recno(num)
+            return self._fix(v)
+
+        def set_range(self, k, dlen=-1, doff=-1) :
+            if isinstance(k, str) :
+                k = bytes(k, charset)
+            v = self._dbcursor.set_range(k, dlen=dlen, doff=doff)
+            return self._fix(v)
+
+        def dup(self, flags=0) :
+            cursor = self._dbcursor.dup(flags)
+            return dup_cursor_py3k(cursor)
+
+        def next_dup(self) :
+            v = self._dbcursor.next_dup()
+            return self._fix(v)
+
+        def put(self, key, value, flags=0, dlen=-1, doff=-1) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            if isinstance(value, str) :
+                value = bytes(value, charset)
+            return self._dbcursor.put(key, value, flags=flags, dlen=dlen,
+                    doff=doff)
+
+        def current(self, flags=0, dlen=-1, doff=-1) :
+            v = self._dbcursor.current(flags=flags, dlen=dlen, doff=doff)
+            return self._fix(v)
+
+        def first(self) :
+            v = self._dbcursor.first()
+            return self._fix(v)
+
+        def pget(self, key=None, data=None, flags=0) :
+            # Incorrect because key can be a bare number,
+            # but enough to pass testsuite
+            if isinstance(key, int) and (data==None) and (flags==0) :
+                flags = key
+                key = None
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            if isinstance(data, int) and (flags==0) :
+                flags = data
+                data = None
+            if isinstance(data, str) :
+                data = bytes(data, charset)
+            v=self._dbcursor.pget(key=key, data=data, flags=flags)
+            if v != None :
+                v1, v2, v3 = v
+                if isinstance(v1, bytes) :
+                    v1 = v1.decode(charset)
+                if isinstance(v2, bytes) :
+                    v2 = v2.decode(charset)
+
+                v = (v1, v2, v3.decode(charset))
+
+            return v
+
+        def join_item(self) :
+            v = self._dbcursor.join_item()
+            if v != None :
+                v = v.decode(charset)
+            return v
+
+        def get(self, *args, **kwargs) :
+            l = len(args)
+            if l == 2 :
+                k, f = args
+                if isinstance(k, str) :
+                    k = bytes(k, "iso8859-1")
+                args = (k, f)
+            elif l == 3 :
+                k, d, f = args
+                if isinstance(k, str) :
+                    k = bytes(k, charset)
+                if isinstance(d, str) :
+                    d = bytes(d, charset)
+                args =(k, d, f)
+
+            v = self._dbcursor.get(*args, **kwargs)
+            if v != None :
+                k, v = v
+                if isinstance(k, bytes) :
+                    k = k.decode(charset)
+                v = (k, v.decode(charset))
+            return v
+
+        def get_both(self, key, value) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            if isinstance(value, str) :
+                value = bytes(value, charset)
+            v=self._dbcursor.get_both(key, value)
+            return self._fix(v)
+
+    class dup_cursor_py3k(cursor_py3k) :
+        def __init__(self, dbcursor) :
+            self._dbcursor = dbcursor
+
+    class DB_py3k(object) :
+        def __init__(self, *args, **kwargs) :
+            args2=[]
+            for i in args :
+                if isinstance(i, DBEnv_py3k) :
+                    i = i._dbenv
+                args2.append(i)
+            args = tuple(args2)
+            for k, v in kwargs.items() :
+                if isinstance(v, DBEnv_py3k) :
+                    kwargs[k] = v._dbenv
+
+            self._db = bsddb._db.DB_orig(*args, **kwargs)
+
+        def __contains__(self, k) :
+            if isinstance(k, str) :
+                k = bytes(k, charset)
+            return getattr(self._db, "has_key")(k)
+
+        def __getitem__(self, k) :
+            if isinstance(k, str) :
+                k = bytes(k, charset)
+            v = self._db[k]
+            if v != None :
+                v = v.decode(charset)
+            return v
+
+        def __setitem__(self, k, v) :
+            if isinstance(k, str) :
+                k = bytes(k, charset)
+            if isinstance(v, str) :
+                v = bytes(v, charset)
+            self._db[k] = v
+
+        def __delitem__(self, k) :
+            if isinstance(k, str) :
+                k = bytes(k, charset)
+            del self._db[k]
+
+        def __getattr__(self, v) :
+            return getattr(self._db, v)
+
+        def __len__(self) :
+            return len(self._db)
+
+        def has_key(self, k, txn=None) :
+            if isinstance(k, str) :
+                k = bytes(k, charset)
+            return self._db.has_key(k, txn=txn)
+
+        def put(self, key, value, txn=None, flags=0, dlen=-1, doff=-1) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            if isinstance(value, str) :
+                value = bytes(value, charset)
+            return self._db.put(key, value, flags=flags, txn=txn, dlen=dlen,
+                    doff=doff)
+
+        def append(self, value, txn=None) :
+            if isinstance(value, str) :
+                value = bytes(value, charset)
+            return self._db.append(value, txn=txn)
+
+        def get_size(self, key) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            return self._db.get_size(key)
+
+        def get(self, key, default="MagicCookie", txn=None, flags=0, dlen=-1, doff=-1) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            if default != "MagicCookie" :  # Magic for 'test_get_none.py'
+                v=self._db.get(key, default=default, txn=txn, flags=flags,
+                        dlen=dlen, doff=doff)
+            else :
+                v=self._db.get(key, txn=txn, flags=flags,
+                        dlen=dlen, doff=doff)
+            if (v != None) and isinstance(v, bytes) :
+                v = v.decode(charset)
+            return v
+
+        def pget(self, key, txn=None) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            v=self._db.pget(key, txn=txn)
+            if v != None :
+                v1, v2 = v
+                if isinstance(v1, bytes) :
+                    v1 = v1.decode(charset)
+
+                v = (v1, v2.decode(charset))
+            return v
+
+        def get_both(self, key, value, txn=None, flags=0) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            if isinstance(value, str) :
+                value = bytes(value, charset)
+            v=self._db.get_both(key, value, txn=txn, flags=flags)
+            if v != None :
+                v = v.decode(charset)
+            return v
+
+        def delete(self, key, txn=None) :
+            if isinstance(key, str) :
+                key = bytes(key, charset)
+            return self._db.delete(key, txn=txn)
+
+        def keys(self) :
+            k = self._db.keys()
+            if len(k) and isinstance(k[0], bytes) :
+                return [i.decode(charset) for i in self._db.keys()]
+            else :
+                return k
+
+        def items(self) :
+            data = self._db.items()
+            if not len(data) : return data
+            data2 = []
+            for k, v in data :
+                if isinstance(k, bytes) :
+                    k = k.decode(charset)
+                data2.append((k, v.decode(charset)))
+            return data2
+
+        def associate(self, secondarydb, callback, flags=0, txn=None) :
+            class associate_callback(object) :
+                def __init__(self, callback) :
+                    self._callback = callback
+
+                def callback(self, key, data) :
+                    if isinstance(key, str) :
+                        key = key.decode(charset)
+                    data = data.decode(charset)
+                    key = self._callback(key, data)
+                    if (key != bsddb._db.DB_DONOTINDEX) and isinstance(key,
+                            str) :
+                        key = bytes(key, charset)
+                    return key
+
+            return self._db.associate(secondarydb._db,
+                    associate_callback(callback).callback, flags=flags, txn=txn)
+
+        def cursor(self, txn=None, flags=0) :
+            return cursor_py3k(self._db, txn=txn, flags=flags)
+
+        def join(self, cursor_list) :
+            cursor_list = [i._dbcursor for i in cursor_list]
+            return dup_cursor_py3k(self._db.join(cursor_list))
+
+    class DBEnv_py3k(object) :
+        def __init__(self, *args, **kwargs) :
+            self._dbenv = bsddb._db.DBEnv_orig(*args, **kwargs)
+
+        def __getattr__(self, v) :
+            return getattr(self._dbenv, v)
+
+    class DBSequence_py3k(object) :
+        def __init__(self, db, *args, **kwargs) :
+            self._db=db
+            self._dbsequence = bsddb._db.DBSequence_orig(db._db, *args, **kwargs)
+
+        def __getattr__(self, v) :
+            return getattr(self._dbsequence, v)
+
+        def open(self, key, *args, **kwargs) :
+            return self._dbsequence.open(bytes(key, charset), *args, **kwargs)
+
+        def get_key(self) :
+            return  self._dbsequence.get_key().decode(charset)
+
+        def get_dbp(self) :
+            return self._db
+
+    import string
+    string.letters=[chr(i) for i in xrange(65,91)]
+
+    bsddb._db.DBEnv_orig = bsddb._db.DBEnv
+    bsddb._db.DB_orig = bsddb._db.DB
+    bsddb._db.DBSequence_orig = bsddb._db.DBSequence
+
+    def do_proxy_db_py3k(flag) :
+        flag2 = do_proxy_db_py3k.flag
+        do_proxy_db_py3k.flag = flag
+        if flag :
+            bsddb.DBEnv = bsddb.db.DBEnv = bsddb._db.DBEnv = DBEnv_py3k
+            bsddb.DB = bsddb.db.DB = bsddb._db.DB = DB_py3k
+            bsddb._db.DBSequence = DBSequence_py3k
+        else :
+            bsddb.DBEnv = bsddb.db.DBEnv = bsddb._db.DBEnv = bsddb._db.DBEnv_orig
+            bsddb.DB = bsddb.db.DB = bsddb._db.DB = bsddb._db.DB_orig
+            bsddb._db.DBSequence = bsddb._db.DBSequence_orig
+        return flag2
+
+    do_proxy_db_py3k.flag = False
+    do_proxy_db_py3k(True)
+
+try:
+    # For Pythons w/distutils pybsddb
+    from bsddb3 import db, dbtables, dbutils, dbshelve, \
+            hashopen, btopen, rnopen, dbobj
+except ImportError:
+    # For Python 2.3
+    from bsddb import db, dbtables, dbutils, dbshelve, \
+            hashopen, btopen, rnopen, dbobj
+
 try:
     from bsddb3 import test_support
 except ImportError:
     from test import test_support
 
+
 try:
-    from threading import Thread, currentThread
-    del Thread, currentThread
+    if sys.version_info[0] < 3 :
+        from threading import Thread, currentThread
+        del Thread, currentThread
+    else :
+        from threading import Thread, current_thread
+        del Thread, current_thread
     have_threads = True
 except ImportError:
     have_threads = False

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	Sun Aug 31 16:00:51 2008
@@ -7,19 +7,8 @@
 from pprint import pprint
 
 import unittest
-from test_all import verbose, have_threads, get_new_environment_path
-
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db, dbshelve
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, dbshelve
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+from test_all import db, dbshelve, test_support, verbose, have_threads, \
+        get_new_environment_path
 
 
 #----------------------------------------------------------------------
@@ -152,7 +141,7 @@
         for key, value in musicdata.items():
             if type(self.keytype) == type(''):
                 key = "%02d" % key
-            d.put(key, string.join(value, '|'), txn=txn)
+            d.put(key, '|'.join(value), txn=txn)
 
     def createDB(self, txn=None):
         self.cur = None
@@ -238,13 +227,13 @@
         rec = self.cur.first()
         while rec is not None:
             if type(self.keytype) == type(''):
-                self.assert_(string.atoi(rec[0]))  # for primary db, key is a number
+                self.assert_(int(rec[0]))  # for primary db, key is a number
             else:
                 self.assert_(rec[0] and type(rec[0]) == type(0))
             count = count + 1
             if verbose:
                 print rec
-            rec = self.cur.next()
+            rec = getattr(self.cur, "next")()
         self.assertEqual(count, len(musicdata))  # all items accounted for
 
 
@@ -270,7 +259,7 @@
             count = count + 1
             if verbose:
                 print rec
-            rec = self.cur.next()
+            rec = getattr(self.cur, "next")()
         # all items accounted for EXCEPT for 1 with "Blues" genre
         self.assertEqual(count, len(musicdata)-1)
 
@@ -278,9 +267,11 @@
 
     def getGenre(self, priKey, priData):
         self.assertEqual(type(priData), type(""))
+        genre = priData.split('|')[2]
+
         if verbose:
             print 'getGenre key: %r data: %r' % (priKey, priData)
-        genre = string.split(priData, '|')[2]
+
         if genre == 'Blues':
             return db.DB_DONOTINDEX
         else:
@@ -404,13 +395,13 @@
         for key, value in musicdata.items():
             if type(self.keytype) == type(''):
                 key = "%02d" % key
-            d.put(key, string.join(value, '|'))
+            d.put(key, '|'.join(value))
 
     def writer2(self, d):
         for x in range(100, 600):
             key = 'z%2d' % x
             value = [key] * 4
-            d.put(key, string.join(value, '|'))
+            d.put(key, '|'.join(value))
 
 
 class ThreadedAssociateHashTestCase(ShelveAssociateTestCase):

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	Sun Aug 31 16:00:51 2008
@@ -10,19 +10,8 @@
 import unittest
 import time
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
-
-from test_all import verbose, get_new_environment_path, get_new_database_path
+from test_all import db, test_support, verbose, get_new_environment_path, \
+        get_new_database_path
 
 DASH = '-'
 
@@ -150,7 +139,11 @@
         try:
             d.delete('abcd')
         except db.DBNotFoundError, val:
-            self.assertEqual(val[0], db.DB_NOTFOUND)
+            import sys
+            if sys.version_info[0] < 3 :
+                self.assertEqual(val[0], db.DB_NOTFOUND)
+            else :
+                self.assertEqual(val.args[0], db.DB_NOTFOUND)
             if verbose: print val
         else:
             self.fail("expected exception")
@@ -169,7 +162,11 @@
         try:
             d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE)
         except db.DBKeyExistError, val:
-            self.assertEqual(val[0], db.DB_KEYEXIST)
+            import sys
+            if sys.version_info[0] < 3 :
+                self.assertEqual(val[0], db.DB_KEYEXIST)
+            else :
+                self.assertEqual(val.args[0], db.DB_KEYEXIST)
             if verbose: print val
         else:
             self.fail("expected exception")
@@ -255,8 +252,10 @@
 
         self.assertEqual(d['new record'], 'a replacement record')
 
-        self.assertEqual(d.has_key('0001'), 1)
-        self.assertEqual(d.has_key('spam'), 0)
+# We check also the positional parameter
+        self.assertEqual(d.has_key('0001', None), 1)
+# We check also the keyword parameter
+        self.assertEqual(d.has_key('spam', txn=None), 0)
 
         items = d.items()
         self.assertEqual(len(items), self._numKeys+1)
@@ -302,7 +301,11 @@
                 rec = c.next()
             except db.DBNotFoundError, val:
                 if get_raises_error:
-                    self.assertEqual(val[0], db.DB_NOTFOUND)
+                    import sys
+                    if sys.version_info[0] < 3 :
+                        self.assertEqual(val[0], db.DB_NOTFOUND)
+                    else :
+                        self.assertEqual(val.args[0], db.DB_NOTFOUND)
                     if verbose: print val
                     rec = None
                 else:
@@ -323,7 +326,11 @@
                 rec = c.prev()
             except db.DBNotFoundError, val:
                 if get_raises_error:
-                    self.assertEqual(val[0], db.DB_NOTFOUND)
+                    import sys
+                    if sys.version_info[0] < 3 :
+                        self.assertEqual(val[0], db.DB_NOTFOUND)
+                    else :
+                        self.assertEqual(val.args[0], db.DB_NOTFOUND)
                     if verbose: print val
                     rec = None
                 else:
@@ -346,7 +353,11 @@
         try:
             n = c.set('bad key')
         except db.DBNotFoundError, val:
-            self.assertEqual(val[0], db.DB_NOTFOUND)
+            import sys
+            if sys.version_info[0] < 3 :
+                self.assertEqual(val[0], db.DB_NOTFOUND)
+            else :
+                self.assertEqual(val.args[0], db.DB_NOTFOUND)
             if verbose: print val
         else:
             if set_raises_error:
@@ -360,7 +371,11 @@
         try:
             n = c.get_both('0404', 'bad data')
         except db.DBNotFoundError, val:
-            self.assertEqual(val[0], db.DB_NOTFOUND)
+            import sys
+            if sys.version_info[0] < 3 :
+                self.assertEqual(val[0], db.DB_NOTFOUND)
+            else :
+                self.assertEqual(val.args[0], db.DB_NOTFOUND)
             if verbose: print val
         else:
             if get_raises_error:
@@ -389,7 +404,11 @@
             rec = c.current()
         except db.DBKeyEmptyError, val:
             if get_raises_error:
-                self.assertEqual(val[0], db.DB_KEYEMPTY)
+                import sys
+                if sys.version_info[0] < 3 :
+                    self.assertEqual(val[0], db.DB_KEYEMPTY)
+                else :
+                    self.assertEqual(val.args[0], db.DB_KEYEMPTY)
                 if verbose: print val
             else:
                 self.fail("unexpected DBKeyEmptyError")
@@ -434,7 +453,11 @@
                 # a bug may cause a NULL pointer dereference...
                 apply(getattr(c, method), args)
             except db.DBError, val:
-                self.assertEqual(val[0], 0)
+                import sys
+                if sys.version_info[0] < 3 :
+                    self.assertEqual(val[0], 0)
+                else :
+                    self.assertEqual(val.args[0], 0)
                 if verbose: print val
             else:
                 self.fail("no exception raised when using a buggy cursor's"
@@ -803,8 +826,8 @@
         rec = c.set("dup1")
         self.assertEqual(rec, ('dup1', 'The'))
 
-        next = c.next()
-        self.assertEqual(next, ('dup1', 'quick'))
+        next_reg = c.next()
+        self.assertEqual(next_reg, ('dup1', 'quick'))
 
         rec = c.set("dup1")
         count = c.count()
@@ -919,7 +942,7 @@
             if verbose:
                 print rec
             rec = c3.next()
-        self.assertEqual(count, 52)
+        self.assertEqual(count, len(string.letters))
 
 
         c1.close()

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	Sun Aug 31 16:00:51 2008
@@ -7,19 +7,10 @@
 from cStringIO import StringIO
 
 import unittest
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db, dbshelve
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, dbshelve
-
-from test_all import get_new_environment_path, get_new_database_path
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+
+from test_all import db, dbshelve, test_support, \
+        get_new_environment_path, get_new_database_path
+
 
 lexical_cmp = cmp
 
@@ -37,7 +28,25 @@
 class ComparatorTests (unittest.TestCase):
     def comparator_test_helper (self, comparator, expected_data):
         data = expected_data[:]
-        data.sort (comparator)
+
+        import sys
+        if sys.version_info[0] < 3 :
+            if sys.version_info[:3] < (2, 4, 0):
+                data.sort(comparator)
+            else :
+                data.sort(cmp=comparator)
+        else :  # Insertion Sort. Please, improve
+            data2 = []
+            for i in data :
+                for j, k in enumerate(data2) :
+                    r = comparator(k, i)
+                    if r == 1 :
+                        data2.insert(j, i)
+                        break
+                else :
+                    data2.append(i)
+            data = data2
+
         self.failUnless (data == expected_data,
                          "comparator `%s' is not right: %s vs. %s"
                          % (comparator, expected_data, data))

Modified: python/trunk/Lib/bsddb/test/test_compat.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_compat.py	(original)
+++ python/trunk/Lib/bsddb/test/test_compat.py	Sun Aug 31 16:00:51 2008
@@ -6,16 +6,10 @@
 import os, string
 import unittest
 
-from test_all import verbose, get_new_database_path
+from test_all import db, hashopen, btopen, rnopen, verbose, \
+        get_new_database_path
 
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db, hashopen, btopen, rnopen
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, hashopen, btopen, rnopen
-
 class CompatibilityTestCase(unittest.TestCase):
     def setUp(self):
         self.filename = get_new_database_path()
@@ -34,7 +28,7 @@
         self.do_bthash_test(hashopen, 'hashopen')
 
     def test03_rnopen(self):
-        data = string.split("The quick brown fox jumped over the lazy dog.")
+        data = "The quick brown fox jumped over the lazy dog.".split()
         if verbose:
             print "\nTesting: rnopen"
 

Modified: python/trunk/Lib/bsddb/test/test_cursor_pget_bug.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_cursor_pget_bug.py	(original)
+++ python/trunk/Lib/bsddb/test/test_cursor_pget_bug.py	Sun Aug 31 16:00:51 2008
@@ -1,19 +1,8 @@
 import unittest
 import os, glob
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-from test_all import get_new_environment_path, get_new_database_path
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+from test_all import db, test_support, get_new_environment_path, \
+        get_new_database_path
 
 #----------------------------------------------------------------------
 

Modified: python/trunk/Lib/bsddb/test/test_dbobj.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_dbobj.py	(original)
+++ python/trunk/Lib/bsddb/test/test_dbobj.py	Sun Aug 31 16:00:51 2008
@@ -2,19 +2,8 @@
 import os, string
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db, dbobj
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, dbobj
-
-from test_all import get_new_environment_path, get_new_database_path
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+from test_all import db, dbobj, test_support, get_new_environment_path, \
+        get_new_database_path
 
 #----------------------------------------------------------------------
 
@@ -36,7 +25,7 @@
         class TestDBEnv(dbobj.DBEnv): pass
         class TestDB(dbobj.DB):
             def put(self, key, *args, **kwargs):
-                key = string.upper(key)
+                key = key.upper()
                 # call our parent classes put method with an upper case key
                 return apply(dbobj.DB.put, (self, key) + args, kwargs)
         self.env = TestDBEnv()

Modified: python/trunk/Lib/bsddb/test/test_dbshelve.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_dbshelve.py	(original)
+++ python/trunk/Lib/bsddb/test/test_dbshelve.py	Sun Aug 31 16:00:51 2008
@@ -4,22 +4,11 @@
 
 import os, string
 import random
-from types import *
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db, dbshelve
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, dbshelve
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
 
-from test_all import verbose, get_new_environment_path, get_new_database_path
+from test_all import db, dbshelve, test_support, verbose, \
+        get_new_environment_path, get_new_database_path
 
 
 
@@ -31,22 +20,38 @@
     def __init__(self):
         self.value = random.random()
 
-    def __cmp__(self, other):
+    def __repr__(self) :  # For Python 3.0 comparison
+        return "DataClass %f" %self.value
+
+    def __cmp__(self, other):  # For Python 2.x comparison
         return cmp(self.value, other)
 
+
 class DBShelveTestCase(unittest.TestCase):
     def setUp(self):
+        import sys
+        if sys.version_info[0] >= 3 :
+            from test_all import do_proxy_db_py3k
+            self._flag_proxy_db_py3k = do_proxy_db_py3k(False)
         self.filename = get_new_database_path()
         self.do_open()
 
     def tearDown(self):
+        import sys
+        if sys.version_info[0] >= 3 :
+            from test_all import do_proxy_db_py3k
+            do_proxy_db_py3k(self._flag_proxy_db_py3k)
         self.do_close()
         test_support.unlink(self.filename)
 
     def mk(self, key):
         """Turn key into an appropriate key type for this db"""
         # override in child class for RECNO
-        return key
+        import sys
+        if sys.version_info[0] < 3 :
+            return key
+        else :
+            return bytes(key, "iso8859-1")  # 8 bits
 
     def populateDB(self, d):
         for x in string.letters:
@@ -112,9 +117,15 @@
 
         dbvalues = d.values()
         self.assertEqual(len(dbvalues), len(d.keys()))
-        values.sort()
-        dbvalues.sort()
-        self.assertEqual(values, dbvalues)
+        import sys
+        if sys.version_info[0] < 3 :
+            values.sort()
+            dbvalues.sort()
+            self.assertEqual(values, dbvalues)
+        else :  # XXX: Convert all to strings. Please, improve
+            values.sort(key=lambda x : str(x))
+            dbvalues.sort(key=lambda x : str(x))
+            self.assertEqual(repr(values), repr(dbvalues))
 
         items = d.items()
         self.assertEqual(len(items), len(values))
@@ -154,7 +165,8 @@
                 print rec
             key, value = rec
             self.checkrec(key, value)
-            rec = c.next()
+            # Hack to avoid conversion by 2to3 tool
+            rec = getattr(c, "next")()
         del c
 
         self.assertEqual(count, len(d))
@@ -190,21 +202,33 @@
 
     def checkrec(self, key, value):
         # override this in a subclass if the key type is different
+
+        import sys
+        if sys.version_info[0] >= 3 :
+            if isinstance(key, bytes) :
+                key = key.decode("iso8859-1")  # 8 bits
+
         x = key[1]
         if key[0] == 'S':
-            self.assertEqual(type(value), StringType)
+            self.assertEqual(type(value), str)
             self.assertEqual(value, 10 * x)
 
         elif key[0] == 'I':
-            self.assertEqual(type(value), IntType)
+            self.assertEqual(type(value), int)
             self.assertEqual(value, ord(x))
 
         elif key[0] == 'L':
-            self.assertEqual(type(value), ListType)
+            self.assertEqual(type(value), list)
             self.assertEqual(value, [x] * 10)
 
         elif key[0] == 'O':
-            self.assertEqual(type(value), InstanceType)
+            import sys
+            if sys.version_info[0] < 3 :
+                from types import InstanceType
+                self.assertEqual(type(value), InstanceType)
+            else :
+                self.assertEqual(type(value), DataClass)
+
             self.assertEqual(value.S, 10 * x)
             self.assertEqual(value.I, ord(x))
             self.assertEqual(value.L, [x] * 10)
@@ -266,6 +290,10 @@
         DBShelveTestCase.setUp(self)
 
     def tearDown(self):
+        import sys
+        if sys.version_info[0] >= 3 :
+            from test_all import do_proxy_db_py3k
+            do_proxy_db_py3k(self._flag_proxy_db_py3k)
         self.do_close()
         test_support.rmtree(self.homeDir)
 

Modified: python/trunk/Lib/bsddb/test/test_dbtables.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_dbtables.py	(original)
+++ python/trunk/Lib/bsddb/test/test_dbtables.py	Sun Aug 31 16:00:51 2008
@@ -28,20 +28,8 @@
     import pickle
 
 import unittest
-from test_all import verbose, get_new_environment_path, get_new_database_path
-
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db, dbtables
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, dbtables
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
-
+from test_all import db, dbtables, test_support, verbose, \
+        get_new_environment_path, get_new_database_path
 
 #----------------------------------------------------------------------
 
@@ -49,12 +37,21 @@
     db_name = 'test-table.db'
 
     def setUp(self):
+        import sys
+        if sys.version_info[0] >= 3 :
+            from test_all import do_proxy_db_py3k
+            self._flag_proxy_db_py3k = do_proxy_db_py3k(False)
+
         self.testHomeDir = get_new_environment_path()
         self.tdb = dbtables.bsdTableDB(
             filename='tabletest.db', dbhome=self.testHomeDir, create=1)
 
     def tearDown(self):
         self.tdb.close()
+        import sys
+        if sys.version_info[0] >= 3 :
+            from test_all import do_proxy_db_py3k
+            do_proxy_db_py3k(self._flag_proxy_db_py3k)
         test_support.rmtree(self.testHomeDir)
 
     def test01(self):
@@ -65,7 +62,12 @@
         except dbtables.TableDBError:
             pass
         self.tdb.CreateTable(tabname, [colname])
-        self.tdb.Insert(tabname, {colname: pickle.dumps(3.14159, 1)})
+        import sys
+        if sys.version_info[0] < 3 :
+            self.tdb.Insert(tabname, {colname: pickle.dumps(3.14159, 1)})
+        else :
+            self.tdb.Insert(tabname, {colname: pickle.dumps(3.14159,
+                1).decode("iso8859-1")})  # 8 bits
 
         if verbose:
             self.tdb._db_print()
@@ -73,7 +75,11 @@
         values = self.tdb.Select(
             tabname, [colname], conditions={colname: None})
 
-        colval = pickle.loads(values[0][colname])
+        import sys
+        if sys.version_info[0] < 3 :
+            colval = pickle.loads(values[0][colname])
+        else :
+            colval = pickle.loads(bytes(values[0][colname], "iso8859-1"))
         self.assert_(colval > 3.141)
         self.assert_(colval < 3.142)
 
@@ -83,11 +89,23 @@
         col0 = 'coolness factor'
         col1 = 'but can it fly?'
         col2 = 'Species'
-        testinfo = [
-            {col0: pickle.dumps(8, 1), col1: 'no', col2: 'Penguin'},
-            {col0: pickle.dumps(-1, 1), col1: 'no', col2: 'Turkey'},
-            {col0: pickle.dumps(9, 1), col1: 'yes', col2: 'SR-71A Blackbird'}
-        ]
+
+        import sys
+        if sys.version_info[0] < 3 :
+            testinfo = [
+                {col0: pickle.dumps(8, 1), col1: 'no', col2: 'Penguin'},
+                {col0: pickle.dumps(-1, 1), col1: 'no', col2: 'Turkey'},
+                {col0: pickle.dumps(9, 1), col1: 'yes', col2: 'SR-71A Blackbird'}
+            ]
+        else :
+            testinfo = [
+                {col0: pickle.dumps(8, 1).decode("iso8859-1"),
+                    col1: 'no', col2: 'Penguin'},
+                {col0: pickle.dumps(-1, 1).decode("iso8859-1"),
+                    col1: 'no', col2: 'Turkey'},
+                {col0: pickle.dumps(9, 1).decode("iso8859-1"),
+                    col1: 'yes', col2: 'SR-71A Blackbird'}
+            ]
 
         try:
             self.tdb.Drop(tabname)
@@ -97,8 +115,14 @@
         for row in testinfo :
             self.tdb.Insert(tabname, row)
 
-        values = self.tdb.Select(tabname, [col2],
-            conditions={col0: lambda x: pickle.loads(x) >= 8})
+        import sys
+        if sys.version_info[0] < 3 :
+            values = self.tdb.Select(tabname, [col2],
+                conditions={col0: lambda x: pickle.loads(x) >= 8})
+        else :
+            values = self.tdb.Select(tabname, [col2],
+                conditions={col0: lambda x:
+                    pickle.loads(bytes(x, "iso8859-1")) >= 8})
 
         self.assertEqual(len(values), 2)
         if values[0]['Species'] == 'Penguin' :

Modified: python/trunk/Lib/bsddb/test/test_distributed_transactions.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_distributed_transactions.py	(original)
+++ python/trunk/Lib/bsddb/test/test_distributed_transactions.py	Sun Aug 31 16:00:51 2008
@@ -4,19 +4,8 @@
 import os
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-from test_all import get_new_environment_path, get_new_database_path
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+from test_all import db, test_support, get_new_environment_path, \
+        get_new_database_path
 
 try :
     a=set()
@@ -79,12 +68,16 @@
 
     def test01_distributed_transactions(self) :
         txns=set()
+        adapt = lambda x : x
+        import sys
+        if sys.version_info[0] >= 3 :
+            adapt = lambda x : bytes(x, "ascii")
     # Create transactions, "prepare" them, and
     # let them be garbage collected.
         for i in xrange(self.num_txns) :
-            txn=self.dbenv.txn_begin()
-            gid="%%%dd" %db.DB_XIDDATASIZE
-            gid=gid %i
+            txn = self.dbenv.txn_begin()
+            gid = "%%%dd" %db.DB_XIDDATASIZE
+            gid = adapt(gid %i)
             self.db.put(i, gid, txn=txn, flags=db.DB_APPEND)
             txns.add(gid)
             txn.prepare(gid)

Modified: python/trunk/Lib/bsddb/test/test_early_close.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_early_close.py	(original)
+++ python/trunk/Lib/bsddb/test/test_early_close.py	Sun Aug 31 16:00:51 2008
@@ -5,19 +5,7 @@
 import os
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
-
-from test_all import verbose, get_new_environment_path, get_new_database_path
+from test_all import db, test_support, verbose, get_new_environment_path, get_new_database_path
 
 # We're going to get warnings in this module about trying to close the db when
 # its env is already closed.  Let's just ignore those.

Modified: python/trunk/Lib/bsddb/test/test_get_none.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_get_none.py	(original)
+++ python/trunk/Lib/bsddb/test/test_get_none.py	Sun Aug 31 16:00:51 2008
@@ -5,14 +5,7 @@
 import os, string
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-from test_all import verbose, get_new_database_path
+from test_all import db, verbose, get_new_database_path
 
 
 #----------------------------------------------------------------------
@@ -39,8 +32,8 @@
         data = d.get('bad key')
         self.assertEqual(data, None)
 
-        data = d.get('a')
-        self.assertEqual(data, 'a'*40)
+        data = d.get(string.letters[0])
+        self.assertEqual(data, string.letters[0]*40)
 
         count = 0
         c = d.cursor()
@@ -50,7 +43,7 @@
             rec = c.next()
 
         self.assertEqual(rec, None)
-        self.assertEqual(count, 52)
+        self.assertEqual(count, len(string.letters))
 
         c.close()
         d.close()
@@ -67,8 +60,8 @@
         self.assertRaises(db.DBNotFoundError, d.get, 'bad key')
         self.assertRaises(KeyError, d.get, 'bad key')
 
-        data = d.get('a')
-        self.assertEqual(data, 'a'*40)
+        data = d.get(string.letters[0])
+        self.assertEqual(data, string.letters[0]*40)
 
         count = 0
         exceptionHappened = 0
@@ -84,7 +77,7 @@
 
         self.assertNotEqual(rec, None)
         self.assert_(exceptionHappened)
-        self.assertEqual(count, 52)
+        self.assertEqual(count, len(string.letters))
 
         c.close()
         d.close()

Modified: python/trunk/Lib/bsddb/test/test_join.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_join.py	(original)
+++ python/trunk/Lib/bsddb/test/test_join.py	Sun Aug 31 16:00:51 2008
@@ -4,22 +4,9 @@
 import os
 
 import unittest
-from test_all import verbose
-
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db, dbshelve
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, dbshelve
-
-from test_all import get_new_environment_path, get_new_database_path
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
 
+from test_all import db, dbshelve, test_support, verbose, \
+        get_new_environment_path, get_new_database_path
 
 #----------------------------------------------------------------------
 

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	Sun Aug 31 16:00:51 2008
@@ -5,23 +5,16 @@
 import time
 
 import unittest
-from test_all import verbose, have_threads, get_new_environment_path, get_new_database_path
+from test_all import db, test_support, 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
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
-
+    from threading import Thread
+    import sys
+    if sys.version_info[0] < 3 :
+        from threading import currentThread
+    else :
+        from threading import current_thread as currentThread
 
 #----------------------------------------------------------------------
 
@@ -87,7 +80,11 @@
                               args=(db.DB_LOCK_WRITE,)))
 
         for t in threads:
-            t.setDaemon(True)
+            import sys
+            if sys.version_info[0] < 3 :
+                t.setDaemon(True)
+            else :
+                t.daemon = True
             t.start()
         for t in threads:
             t.join()
@@ -111,7 +108,11 @@
         deadlock_detection.end=False
         deadlock_detection.count=0
         t=Thread(target=deadlock_detection)
-        t.setDaemon(True)
+        import sys
+        if sys.version_info[0] < 3 :
+            t.setDaemon(True)
+        else :
+            t.daemon = True
         t.start()
         self.env.set_timeout(100000, db.DB_SET_LOCK_TIMEOUT)
         anID = self.env.lock_id()
@@ -134,7 +135,12 @@
             self.assertTrue(deadlock_detection.count>0)
 
     def theThread(self, lockType):
-        name = currentThread().getName()
+        import sys
+        if sys.version_info[0] < 3 :
+            name = currentThread().getName()
+        else :
+            name = currentThread().name
+
         if lockType ==  db.DB_LOCK_WRITE:
             lt = "write"
         else:

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	Sun Aug 31 16:00:51 2008
@@ -4,19 +4,7 @@
 import os
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db, dbshelve, hashopen
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, dbshelve, hashopen
-
-from test_all import get_new_environment_path, get_new_database_path
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+from test_all import db, dbshelve, hashopen, test_support, get_new_environment_path, get_new_database_path
 
 #----------------------------------------------------------------------
 
@@ -39,7 +27,11 @@
         # check for crash fixed when db_home is used before open()
         self.assert_(env.db_home is None)
         env.open(self.homeDir, db.DB_CREATE)
-        self.assertEqual(self.homeDir, env.db_home)
+        import sys
+        if sys.version_info[0] < 3 :
+            self.assertEqual(self.homeDir, env.db_home)
+        else :
+            self.assertEqual(bytes(self.homeDir, "ascii"), env.db_home)
 
     def test03_repr_closed_db(self):
         db = hashopen(self.filename)

Modified: python/trunk/Lib/bsddb/test/test_pickle.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_pickle.py	(original)
+++ python/trunk/Lib/bsddb/test/test_pickle.py	Sun Aug 31 16:00:51 2008
@@ -7,20 +7,7 @@
     cPickle = None
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError, e:
-    # For Python 2.3
-    from bsddb import db
-
-from test_all import get_new_environment_path, get_new_database_path
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
-
+from test_all import db, test_support, get_new_environment_path, get_new_database_path
 
 #----------------------------------------------------------------------
 

Modified: python/trunk/Lib/bsddb/test/test_queue.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_queue.py	(original)
+++ python/trunk/Lib/bsddb/test/test_queue.py	Sun Aug 31 16:00:51 2008
@@ -6,15 +6,7 @@
 from pprint import pprint
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-from test_all import verbose, get_new_database_path
-
+from test_all import db, verbose, get_new_database_path
 
 #----------------------------------------------------------------------
 
@@ -47,14 +39,14 @@
         for x in string.letters:
             d.append(x * 40)
 
-        self.assertEqual(len(d), 52)
+        self.assertEqual(len(d), len(string.letters))
 
         d.put(100, "some more data")
         d.put(101, "and some more ")
         d.put(75,  "out of order")
         d.put(1,   "replacement data")
 
-        self.assertEqual(len(d), 55)
+        self.assertEqual(len(d), len(string.letters)+3)
 
         if verbose:
             print "before close" + '-' * 30
@@ -69,7 +61,11 @@
             print "after open" + '-' * 30
             pprint(d.stat())
 
-        d.append("one more")
+        # Test "txn" as a positional parameter
+        d.append("one more", None)
+        # Test "txn" as a keyword parameter
+        d.append("another one", txn=None)
+
         c = d.cursor()
 
         if verbose:
@@ -119,14 +115,14 @@
         for x in string.letters:
             d.append(x * 40)
 
-        self.assertEqual(len(d), 52)
+        self.assertEqual(len(d), len(string.letters))
 
         d.put(100, "some more data")
         d.put(101, "and some more ")
         d.put(75,  "out of order")
         d.put(1,   "replacement data")
 
-        self.assertEqual(len(d), 55)
+        self.assertEqual(len(d), len(string.letters)+3)
 
         if verbose:
             print "before close" + '-' * 30

Modified: python/trunk/Lib/bsddb/test/test_recno.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_recno.py	(original)
+++ python/trunk/Lib/bsddb/test/test_recno.py	Sun Aug 31 16:00:51 2008
@@ -6,19 +6,7 @@
 from pprint import pprint
 import unittest
 
-from test_all import verbose, get_new_environment_path, get_new_database_path
-
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+from test_all import db, test_support, verbose, get_new_environment_path, get_new_database_path
 
 letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
@@ -72,7 +60,11 @@
         try:
             data = d[0]  # This should raise a KeyError!?!?!
         except db.DBInvalidArgError, val:
-            self.assertEqual(val[0], db.EINVAL)
+            import sys
+            if sys.version_info[0] < 3 :
+                self.assertEqual(val[0], db.EINVAL)
+            else :
+                self.assertEqual(val.args[0], db.EINVAL)
             if verbose: print val
         else:
             self.fail("expected exception")
@@ -277,7 +269,11 @@
         try:                    # this one will fail
             d.append('bad' * 20)
         except db.DBInvalidArgError, val:
-            self.assertEqual(val[0], db.EINVAL)
+            import sys
+            if sys.version_info[0] < 3 :
+                self.assertEqual(val[0], db.EINVAL)
+            else :
+                self.assertEqual(val.args[0], db.EINVAL)
             if verbose: print val
         else:
             self.fail("expected exception")

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	Sun Aug 31 16:00:51 2008
@@ -5,21 +5,9 @@
 import time
 import unittest
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    # For Python 2.3
-    from bsddb import db
-
-from test_all import have_threads, get_new_environment_path, get_new_database_path
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+from test_all import db, test_support, have_threads, verbose, \
+        get_new_environment_path, get_new_database_path
 
-from test_all import verbose
 
 #----------------------------------------------------------------------
 
@@ -254,9 +242,14 @@
 
         from threading import Thread
         t_m=Thread(target=thread_master)
-        t_m.setDaemon(True)
         t_c=Thread(target=thread_client)
-        t_c.setDaemon(True)
+        import sys
+        if sys.version_info[0] < 3 :
+            t_m.setDaemon(True)
+            t_c.setDaemon(True)
+        else :
+            t_m.daemon = True
+            t_c.daemon = True
 
         self.t_m = t_m
         self.t_c = t_c
@@ -400,7 +393,11 @@
                             from threading import Thread
                             election_status[0] = True
                             t=Thread(target=elect)
-                            t.setDaemon(True)
+                            import sys
+                            if sys.version_info[0] < 3 :
+                                t.setDaemon(True)
+                            else :
+                                t.daemon = True
                             t.start()
 
             self.thread_do = thread_do

Modified: python/trunk/Lib/bsddb/test/test_sequence.py
==============================================================================
--- python/trunk/Lib/bsddb/test/test_sequence.py	(original)
+++ python/trunk/Lib/bsddb/test/test_sequence.py	Sun Aug 31 16:00:51 2008
@@ -1,18 +1,7 @@
 import unittest
 import os
 
-try:
-    # For Pythons w/distutils pybsddb
-    from bsddb3 import db
-except ImportError:
-    from bsddb import db
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
-
-from test_all import get_new_environment_path, get_new_database_path
+from test_all import db, test_support, get_new_environment_path, get_new_database_path
 
 
 class DBSequenceTest(unittest.TestCase):

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	Sun Aug 31 16:00:51 2008
@@ -16,23 +16,16 @@
         pass
 
 import unittest
-from test_all import verbose, have_threads, get_new_environment_path, get_new_database_path
+from test_all import db, dbutils, test_support, 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
-    from bsddb3 import db, dbutils
-except ImportError:
-    # For Python 2.3
-    from bsddb import db, dbutils
-
-try:
-    from bsddb3 import test_support
-except ImportError:
-    from test import test_support
+    from threading import Thread
+    import sys
+    if sys.version_info[0] < 3 :
+        from threading import currentThread
+    else :
+        from threading import current_thread as currentThread
 
 
 #----------------------------------------------------------------------
@@ -106,7 +99,11 @@
                         args = (self.d, x),
                         name = 'reader %d' % x,
                         )#verbose = verbose)
-            rt.setDaemon(True)
+            import sys
+            if sys.version_info[0] < 3 :
+                rt.setDaemon(True)
+            else :
+                rt.daemon = True
             readers.append(rt)
 
         writers=[]
@@ -121,7 +118,11 @@
             writers.append(wt)
 
         for t in writers:
-            t.setDaemon(True)
+            import sys
+            if sys.version_info[0] < 3 :
+                t.setDaemon(True)
+            else :
+                t.daemon = True
             t.start()
 
         for t in writers:
@@ -130,7 +131,12 @@
             t.join()
 
     def writerThread(self, d, keys, readers):
-        name = currentThread().getName()
+        import sys
+        if sys.version_info[0] < 3 :
+            name = currentThread().getName()
+        else :
+            name = currentThread().name
+
         if verbose:
             print "%s: creating records %d - %d" % (name, start, stop)
 
@@ -155,7 +161,11 @@
             print "%s: thread finished" % name
 
     def readerThread(self, d, readerNum):
-        name = currentThread().getName()
+        import sys
+        if sys.version_info[0] < 3 :
+            name = currentThread().getName()
+        else :
+            name = currentThread().name
 
         for i in xrange(5) :
             c = d.cursor()
@@ -221,7 +231,11 @@
                         args = (self.d, x),
                         name = 'reader %d' % x,
                         )#verbose = verbose)
-            rt.setDaemon(True)
+            import sys
+            if sys.version_info[0] < 3 :
+                rt.setDaemon(True)
+            else :
+                rt.daemon = True
             readers.append(rt)
 
         writers = []
@@ -236,7 +250,11 @@
             writers.append(wt)
 
         for t in writers:
-            t.setDaemon(True)
+            import sys
+            if sys.version_info[0] < 3 :
+                t.setDaemon(True)
+            else :
+                t.daemon = True
             t.start()
 
         for t in writers:
@@ -245,7 +263,11 @@
             t.join()
 
     def writerThread(self, d, keys, readers):
-        name = currentThread().getName()
+        import sys
+        if sys.version_info[0] < 3 :
+            name = currentThread().getName()
+        else :
+            name = currentThread().name
         if verbose:
             print "%s: creating records %d - %d" % (name, start, stop)
 
@@ -268,7 +290,11 @@
             print "%s: thread finished" % name
 
     def readerThread(self, d, readerNum):
-        name = currentThread().getName()
+        import sys
+        if sys.version_info[0] < 3 :
+            name = currentThread().getName()
+        else :
+            name = currentThread().name
 
         c = d.cursor()
         count = 0
@@ -335,7 +361,11 @@
                         args = (self.d, x),
                         name = 'reader %d' % x,
                         )#verbose = verbose)
-            rt.setDaemon(True)
+            import sys
+            if sys.version_info[0] < 3 :
+                rt.setDaemon(True)
+            else :
+                rt.daemon = True
             readers.append(rt)
 
         writers = []
@@ -349,11 +379,19 @@
             writers.append(wt)
 
         dt = Thread(target = self.deadlockThread)
-        dt.setDaemon(True)
+        import sys
+        if sys.version_info[0] < 3 :
+            dt.setDaemon(True)
+        else :
+            dt.daemon = True
         dt.start()
 
         for t in writers:
-            t.setDaemon(True)
+            import sys
+            if sys.version_info[0] < 3 :
+                t.setDaemon(True)
+            else :
+                t.daemon = True
             t.start()
 
         for t in writers:
@@ -365,7 +403,12 @@
         dt.join()
 
     def writerThread(self, d, keys, readers):
-        name = currentThread().getName()
+        import sys
+        if sys.version_info[0] < 3 :
+            name = currentThread().getName()
+        else :
+            name = currentThread().name
+
         count=len(keys)//len(readers)
         while len(keys):
             try:
@@ -388,7 +431,11 @@
             print "%s: thread finished" % name
 
     def readerThread(self, d, readerNum):
-        name = currentThread().getName()
+        import sys
+        if sys.version_info[0] < 3 :
+            name = currentThread().getName()
+        else :
+            name = currentThread().name
 
         finished = False
         while not finished:

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Sun Aug 31 16:00:51 2008
@@ -488,8 +488,9 @@
 
 - Support for Windows 9x has been removed from the winsound module.
 
-- bsddb module updated to version 4.7.0.
-  http://www.jcea.es/programacion/pybsddb.htm#bsddb3-4.7.0
+- bsddb module updated to version 4.7.3pre2.
+  http://www.jcea.es/programacion/pybsddb.htm#bsddb3-4.7.3. This
+  code should be compatible with Python 3.0.
 
 - Issue #2858: Fix potential memory corruption when
   bsddb.db.DBEnv.lock_get and other bsddb.db object constructors
@@ -2655,8 +2656,8 @@
 - fixed a bug with bsddb.DB.stat: the flags and txn keyword arguments
   were transposed.
 
-- Added support for linking the bsddb module against BerkeleyDB 4.5.x
-  and 4.6.x.
+- Added support for linking the bsddb module against BerkeleyDB 4.5.x,
+  4.6.x and 4.7.x.
 
 - Bug #1633621: if curses.resizeterm() or curses.resize_term() is
   called, update _curses.LINES, _curses.COLS, curses.LINES and

Modified: python/trunk/Modules/_bsddb.c
==============================================================================
--- python/trunk/Modules/_bsddb.c	(original)
+++ python/trunk/Modules/_bsddb.c	Sun Aug 31 16:00:51 2008
@@ -396,7 +396,11 @@
     }
     else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
         PyErr_SetString(PyExc_TypeError,
+#if (PY_VERSION_HEX < 0x03000000)
                         "Data values must be of type string or None.");
+#else
+                        "Data values must be of type bytes or None.");
+#endif
         return 0;
     }
     return 1;
@@ -435,7 +439,11 @@
         if (type == DB_RECNO || type == DB_QUEUE) {
             PyErr_SetString(
                 PyExc_TypeError,
+#if (PY_VERSION_HEX < 0x03000000)
                 "String keys not allowed for Recno and Queue DB's");
+#else
+                "Bytes keys not allowed for Recno and Queue DB's");
+#endif
             return 0;
         }
 
@@ -488,7 +496,11 @@
     }
     else {
         PyErr_Format(PyExc_TypeError,
+#if (PY_VERSION_HEX < 0x03000000)
                      "String or Integer object expected for key, %s found",
+#else
+                     "Bytes or Integer object expected for key, %s found",
+#endif
                      Py_TYPE(keyobj)->tp_name);
         return 0;
     }
@@ -573,11 +585,13 @@
     p=DummyString;
     assert(s==0);
   }
-  return Py_BuildValue("s#",p,s);
+  return PyBytes_FromStringAndSize(p, s);
 }
 
 static PyObject *BuildValue_SS(const void *p1,int s1,const void *p2,int s2)
 {
+PyObject *a, *b, *r;
+
   if (!p1) {
     p1=DummyString;
     assert(s1==0);
@@ -586,25 +600,59 @@
     p2=DummyString;
     assert(s2==0);
   }
-  return Py_BuildValue("s#s#",p1,s1,p2,s2);
+
+  if (!(a = PyBytes_FromStringAndSize(p1, s1))) {
+      return NULL;
+  }
+  if (!(b = PyBytes_FromStringAndSize(p2, s2))) {
+      Py_DECREF(a);
+      return NULL;
+  }
+
+#if (PY_VERSION_HEX >= 0x02040000)
+  r = PyTuple_Pack(2, a, b) ;
+#else
+  r = Py_BuildValue("OO", a, b);
+#endif
+  Py_DECREF(a);
+  Py_DECREF(b);
+  return r;
 }
 
 static PyObject *BuildValue_IS(int i,const void *p,int s)
 {
+  PyObject *a, *r;
+
   if (!p) {
     p=DummyString;
     assert(s==0);
   }
-  return Py_BuildValue("is#",i,p,s);
+
+  if (!(a = PyBytes_FromStringAndSize(p, s))) {
+      return NULL;
+  }
+
+  r = Py_BuildValue("iO", i, a);
+  Py_DECREF(a);
+  return r;
 }
 
-static PyObject *BuildValue_LS(long i,const void *p,int s)
+static PyObject *BuildValue_LS(long l,const void *p,int s)
 {
+  PyObject *a, *r;
+
   if (!p) {
     p=DummyString;
     assert(s==0);
   }
-  return Py_BuildValue("ls#",i,p,s);
+
+  if (!(a = PyBytes_FromStringAndSize(p, s))) {
+      return NULL;
+  }
+
+  r = Py_BuildValue("lO", l, a);
+  Py_DECREF(a);
+  return r;
 }
 
 
@@ -895,7 +943,7 @@
     self->btCompareCallback = NULL;
     self->primaryDBType = 0;
     Py_INCREF(Py_None);
-    self->private = Py_None;
+    self->private_obj = Py_None;
     self->in_weakreflist = NULL;
 
     /* keep a reference to our python DBEnv object */
@@ -967,7 +1015,7 @@
         Py_DECREF(self->btCompareCallback);
         self->btCompareCallback = NULL;
     }
-    Py_DECREF(self->private);
+    Py_DECREF(self->private_obj);
     PyObject_Del(self);
 }
 
@@ -1030,7 +1078,7 @@
     self->children_dbs = NULL;
     self->children_txns = NULL;
     Py_INCREF(Py_None);
-    self->private = Py_None;
+    self->private_obj = Py_None;
     Py_INCREF(Py_None);
     self->rep_transport = Py_None;
     self->in_weakreflist = NULL;
@@ -1045,7 +1093,7 @@
     }
     else {
         self->db_env->set_errcall(self->db_env, _db_errorCallback);
-        self->db_env->app_private=self;
+        self->db_env->app_private = self;
     }
     return self;
 }
@@ -1069,7 +1117,7 @@
     if (self->in_weakreflist != NULL) {
         PyObject_ClearWeakRefs((PyObject *) self);
     }
-    Py_DECREF(self->private);
+    Py_DECREF(self->private_obj);
     Py_DECREF(self->rep_transport);
     PyObject_Del(self);
 }
@@ -1248,15 +1296,17 @@
 /* DB methods */
 
 static PyObject*
-DB_append(DBObject* self, PyObject* args)
+DB_append(DBObject* self, PyObject* args, PyObject* kwargs)
 {
     PyObject* txnobj = NULL;
     PyObject* dataobj;
     db_recno_t recno;
     DBT key, data;
     DB_TXN *txn = NULL;
+    static char* kwnames[] = { "data", "txn", NULL };
 
-    if (!PyArg_UnpackTuple(args, "append", 1, 2, &dataobj, &txnobj))
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:append", kwnames,
+                                     &dataobj, &txnobj))
         return NULL;
 
     CHECK_DB_NOT_CLOSED(self);
@@ -1443,6 +1493,7 @@
     if (self->db != NULL) {
         /* Can be NULL if db is not in an environment */
         EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
+
         if (self->txn) {
             EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
             self->txn=NULL;
@@ -2168,7 +2219,12 @@
         return NULL;
     CHECK_DB_NOT_CLOSED(self);
 
+    EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
     err = self->db->remove(self->db, filename, database, flags);
+    MYDB_END_ALLOW_THREADS;
+
     self->db = NULL;
     RETURN_IF_ERR();
     RETURN_NONE();
@@ -2201,17 +2257,17 @@
 DB_get_private(DBObject* self)
 {
     /* We can give out the private field even if db is closed */
-    Py_INCREF(self->private);
-    return self->private;
+    Py_INCREF(self->private_obj);
+    return self->private_obj;
 }
 
 static PyObject*
-DB_set_private(DBObject* self, PyObject* private)
+DB_set_private(DBObject* self, PyObject* private_obj)
 {
     /* We can set the private field even if db is closed */
-    Py_DECREF(self->private);
-    Py_INCREF(private);
-    self->private = private;
+    Py_DECREF(self->private_obj);
+    Py_INCREF(private_obj);
+    self->private_obj = private_obj;
     RETURN_NONE();
 }
 
@@ -2990,16 +3046,19 @@
 
 
 static PyObject*
-DB_has_key(DBObject* self, PyObject* args)
+DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
 {
     int err;
     PyObject* keyobj;
     DBT key, data;
     PyObject* txnobj = NULL;
     DB_TXN *txn = NULL;
+    static char* kwnames[] = {"key","txn", NULL};
 
-    if (!PyArg_UnpackTuple(args,"has_key", 1, 2, &keyobj, &txnobj))
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
+                &keyobj, &txnobj))
         return NULL;
+
     CHECK_DB_NOT_CLOSED(self);
     if (!make_key_dbt(self, keyobj, &key, NULL))
         return NULL;
@@ -3308,7 +3367,7 @@
     {
         PyErr_Clear();
         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
-                                         &kwnames[1], 
+                                         &kwnames[1],
 					 &keyobj, &flags, &dlen, &doff))
         {
             PyErr_Clear();
@@ -4920,17 +4979,17 @@
 DBEnv_get_private(DBEnvObject* self)
 {
     /* We can give out the private field even if dbenv is closed */
-    Py_INCREF(self->private);
-    return self->private;
+    Py_INCREF(self->private_obj);
+    return self->private_obj;
 }
 
 static PyObject*
-DBEnv_set_private(DBEnvObject* self, PyObject* private)
+DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
 {
     /* We can set the private field even if dbenv is closed */
-    Py_DECREF(self->private);
-    Py_INCREF(private);
-    self->private = private;
+    Py_DECREF(self->private_obj);
+    Py_INCREF(private_obj);
+    self->private_obj = private_obj;
     RETURN_NONE();
 }
 
@@ -5116,8 +5175,18 @@
             return Py_BuildValue("(iO)", err, Py_None);
             break;
         case DB_REP_NEWSITE :
-            return Py_BuildValue("(is#)", err, rec.data, rec.size);
-            break;
+            {
+                PyObject *tmp, *r;
+
+                if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
+                    return NULL;
+                }
+
+                r = Py_BuildValue("(iO)", err, tmp);
+                Py_DECREF(tmp);
+                return r;
+                break;
+            }
 #if (DBVER >= 42)
         case DB_REP_NOTPERM :
         case DB_REP_ISPERM :
@@ -5136,6 +5205,7 @@
     DBEnvObject *dbenv;
     PyObject* rep_transport;
     PyObject* args;
+    PyObject *a, *b;
     PyObject* result = NULL;
     int ret=0;
 
@@ -5143,15 +5213,21 @@
     dbenv = (DBEnvObject *)db_env->app_private;
     rep_transport = dbenv->rep_transport;
 
+    /*
+    ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
+    */
+    a = PyBytes_FromStringAndSize(control->data, control->size);
+    b = PyBytes_FromStringAndSize(rec->data, rec->size);
+
     args = Py_BuildValue(
 #if (PY_VERSION_HEX >= 0x02040000)
-            "(Os#s#(ll)iI)",
+            "(OOO(ll)iI)",
 #else
-            "(Os#s#(ll)ii)",
+            "(OOO(ll)ii)",
 #endif
             dbenv,
-            control->data, control->size,
-            rec->data, rec->size, lsn->file, lsn->offset, envid, flags);
+            a, b,
+            lsn->file, lsn->offset, envid, flags);
     if (args) {
         result = PyEval_CallObject(rep_transport, args);
     }
@@ -5160,6 +5236,8 @@
         PyErr_Print();
         ret = -1;
     }
+    Py_XDECREF(a);
+    Py_XDECREF(b);
     Py_XDECREF(args);
     Py_XDECREF(result);
     MYDB_END_BLOCK_THREADS;
@@ -6259,7 +6337,7 @@
 /* Method definition tables and type objects */
 
 static PyMethodDef DB_methods[] = {
-    {"append",          (PyCFunction)DB_append,         METH_VARARGS},
+    {"append",          (PyCFunction)DB_append,         METH_VARARGS|METH_KEYWORDS},
     {"associate",       (PyCFunction)DB_associate,      METH_VARARGS|METH_KEYWORDS},
     {"close",           (PyCFunction)DB_close,          METH_VARARGS},
     {"consume",         (PyCFunction)DB_consume,        METH_VARARGS|METH_KEYWORDS},
@@ -6275,7 +6353,7 @@
     {"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},
+    {"has_key",         (PyCFunction)DB_has_key,        METH_VARARGS|METH_KEYWORDS},
     {"items",           (PyCFunction)DB_items,          METH_VARARGS},
     {"keys",            (PyCFunction)DB_keys,           METH_VARARGS},
     {"open",            (PyCFunction)DB_open,           METH_VARARGS|METH_KEYWORDS},

Modified: python/trunk/Modules/bsddb.h
==============================================================================
--- python/trunk/Modules/bsddb.h	(original)
+++ python/trunk/Modules/bsddb.h	Sun Aug 31 16:00:51 2008
@@ -105,7 +105,7 @@
 #error "eek! DBVER can't handle minor versions > 9"
 #endif
 
-#define PY_BSDDB_VERSION "4.7.2devel9"
+#define PY_BSDDB_VERSION "4.7.3pre2"
 
 /* Python object definitions */
 
@@ -134,7 +134,7 @@
     PyObject*       event_notifyCallback;
     struct DBObject *children_dbs;
     struct DBTxnObject *children_txns;
-    PyObject        *private;
+    PyObject        *private_obj;
     PyObject        *rep_transport;
     PyObject        *in_weakreflist; /* List of weak references */
 } DBEnvObject;
@@ -159,7 +159,7 @@
     PyObject*       associateCallback;
     PyObject*       btCompareCallback;
     int             primaryDBType;
-    PyObject        *private;
+    PyObject        *private_obj;
     PyObject        *in_weakreflist; /* List of weak references */
 } DBObject;
 


More information about the Python-checkins mailing list