Improve compatibility with Python3.0 testsuite
diff --git a/Lib/bsddb/__init__.py b/Lib/bsddb/__init__.py
index d483139..5dea0f8 100644
--- a/Lib/bsddb/__init__.py
+++ b/Lib/bsddb/__init__.py
@@ -110,7 +110,7 @@
                 key = _DeadlockWrap(cur.first, 0,0,0)[0]
                 yield key
 
-                next = cur.__next__
+                next = getattr(cur, "next")
                 while 1:
                     try:
                         key = _DeadlockWrap(next, 0,0,0)[0]
@@ -123,7 +123,7 @@
                         # FIXME-20031101-greg: race condition.  cursor could
                         # be closed by another thread before this call.
                         _DeadlockWrap(cur.set, key,0,0,0)
-                        next = cur.__next__
+                        next = getattr(cur, "next")
             except _bsddb.DBNotFoundError:
                 pass
             except _bsddb.DBCursorClosedError:
@@ -152,7 +152,7 @@
                 key = kv[0]
                 yield kv
 
-                next = cur.__next__
+                next = getattr(cur, "next")
                 while 1:
                     try:
                         kv = _DeadlockWrap(next)
@@ -166,7 +166,7 @@
                         # FIXME-20031101-greg: race condition.  cursor could
                         # be closed by another thread before this call.
                         _DeadlockWrap(cur.set, key,0,0,0)
-                        next = cur.__next__
+                        next = getattr(cur, "next")
             except _bsddb.DBNotFoundError:
                 pass
             except _bsddb.DBCursorClosedError:
@@ -302,12 +302,15 @@
         self._checkCursor()
         return _DeadlockWrap(self.dbc.set_range, key)
 
-    def __next__(self):
+    def __next__(self):  # Renamed by "2to3"
         self._checkOpen()
         self._checkCursor()
-        rv = _DeadlockWrap(self.dbc.__next__)
+        rv = _DeadlockWrap(getattr(self.dbc, "next"))
         return rv
 
+    if sys.version_info[0] >= 3 :  # For "2to3" conversion
+        next = __next__
+
     def previous(self):
         self._checkOpen()
         self._checkCursor()
diff --git a/Lib/bsddb/test/test_all.py b/Lib/bsddb/test/test_all.py
index d49c429..9a4d3ee 100644
--- a/Lib/bsddb/test/test_all.py
+++ b/Lib/bsddb/test/test_all.py
@@ -33,6 +33,8 @@
             v = getattr(self._dbcursor, "next")()
             return self._fix(v)
 
+        next = __next__
+
         def previous(self) :
             v = self._dbcursor.previous()
             return self._fix(v)
diff --git a/Lib/test/test_bsddb.py b/Lib/test/test_bsddb.py
index a722d8c..666f92c 100755
--- a/Lib/test/test_bsddb.py
+++ b/Lib/test/test_bsddb.py
@@ -13,8 +13,151 @@
     openflag = 'c'
 
     def do_open(self, *args, **kw):
+        # This code will be vastly improved in future bsddb 4.7.4. Meanwhile,
+        # let's live with this ugliness. XXX - jcea@jcea.es - 20080902
+        class _ExposedProperties:
+            @property
+            def _cursor_refs(self):
+                return self.db._cursor_refs
+
+        import collections
+        class StringKeys(collections.MutableMapping, _ExposedProperties):
+            """Wrapper around DB object that automatically encodes
+            all keys as UTF-8; the keys must be strings."""
+
+            def __init__(self, db):
+                self.db = db
+
+            def __len__(self):
+                return len(self.db)
+
+            def __getitem__(self, key):
+                return self.db[key.encode("utf-8")]
+
+            def __setitem__(self, key, value):
+                self.db[key.encode("utf-8")] = value
+
+            def __delitem__(self, key):
+                del self.db[key.encode("utf-8")]
+
+            def __iter__(self):
+                for k in self.db:
+                    yield k.decode("utf-8")
+
+            def close(self):
+                self.db.close()
+
+            def keys(self):
+                for k in self.db.keys():
+                    yield k.decode("utf-8")
+
+            def has_key(self, key):
+                return self.db.has_key(key.encode("utf-8"))
+
+            __contains__ = has_key
+
+            def values(self):
+                return self.db.values()
+
+            def items(self):
+                for k,v in self.db.items():
+                    yield k.decode("utf-8"), v
+
+            def set_location(self, key):
+                return self.db.set_location(key.encode("utf-8"))
+
+            def next(self):
+                key, value = self.db.next()
+                return key.decode("utf-8"), value
+
+            def previous(self):
+                key, value = self.db.previous()
+                return key.decode("utf-8"), value
+
+            def first(self):
+                key, value = self.db.first()
+                return key.decode("utf-8"), value
+
+            def last(self):
+                key, value = self.db.last()
+                return key.decode("utf-8"), value
+
+            def set_location(self, key):
+                key, value = self.db.set_location(key.encode("utf-8"))
+                return key.decode("utf-8"), value
+
+            def sync(self):
+                return self.db.sync()
+
+        class StringValues(collections.MutableMapping, _ExposedProperties):
+            """Wrapper around DB object that automatically encodes
+            and decodes all values as UTF-8; input values must be strings."""
+
+            def __init__(self, db):
+                self.db = db
+
+            def __len__(self):
+                return len(self.db)
+
+            def __getitem__(self, key):
+                return self.db[key].decode("utf-8")
+
+            def __setitem__(self, key, value):
+                self.db[key] = value.encode("utf-8")
+
+            def __delitem__(self, key):
+                del self.db[key]
+
+            def __iter__(self):
+                return iter(self.db)
+
+            def close(self):
+                self.db.close()
+
+            def keys(self):
+                return self.db.keys()
+
+            def has_key(self, key):
+                return self.db.has_key(key)
+
+            __contains__ = has_key
+
+            def values(self):
+                for v in self.db.values():
+                    yield v.decode("utf-8")
+
+            def items(self):
+                for k,v in self.db.items():
+                    yield k, v.decode("utf-8")
+
+            def set_location(self, key):
+                return self.db.set_location(key)
+
+            def next(self):
+                key, value = self.db.next()
+                return key, value.decode("utf-8")
+
+            def previous(self):
+                key, value = self.db.previous()
+                return key, value.decode("utf-8")
+
+            def first(self):
+                key, value = self.db.first()
+                return key, value.decode("utf-8")
+
+            def last(self):
+                key, value = self.db.last()
+                return key, value.decode("utf-8")
+
+            def set_location(self, key):
+                key, value = self.db.set_location(key)
+                return key, value.decode("utf-8")
+
+            def sync(self):
+                return self.db.sync()
+
         # openmethod is a list so that it's not mistaken as an instance method
-        return bsddb.StringValues(bsddb.StringKeys(self.openmethod[0](*args, **kw)))
+        return StringValues(StringKeys(self.openmethod[0](*args, **kw)))
 
     def setUp(self):
         self.f = self.do_open(self.fname, self.openflag, cachesize=32768)
diff --git a/Modules/bsddb.h b/Modules/bsddb.h
index 41f1db9..af5e56b 100644
--- a/Modules/bsddb.h
+++ b/Modules/bsddb.h
@@ -105,7 +105,7 @@
 #error "eek! DBVER can't handle minor versions > 9"
 #endif
 
-#define PY_BSDDB_VERSION "4.7.3pre2"
+#define PY_BSDDB_VERSION "4.7.3pre3"
 
 /* Python object definitions */