summaryrefslogtreecommitdiffstats
path: root/Lib/bsddb
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/bsddb')
-rw-r--r--Lib/bsddb/dbshelve.py41
-rw-r--r--Lib/bsddb/test/test_misc.py28
2 files changed, 52 insertions, 17 deletions
diff --git a/Lib/bsddb/dbshelve.py b/Lib/bsddb/dbshelve.py
index 87be3d1..8264f2d 100644
--- a/Lib/bsddb/dbshelve.py
+++ b/Lib/bsddb/dbshelve.py
@@ -30,11 +30,21 @@ storage.
#------------------------------------------------------------------------
import pickle
-try:
+import sys
+
+#At version 2.3 cPickle switched to using protocol instead of bin and
+#DictMixin was added
+if sys.version_info[:3] >= (2, 3, 0):
+ HIGHEST_PROTOCOL = pickle.HIGHEST_PROTOCOL
+ def _dumps(object, protocol):
+ return pickle.dumps(object, protocol=protocol)
from UserDict import DictMixin
-except ImportError:
- # DictMixin is new in Python 2.3
+else:
+ HIGHEST_PROTOCOL = None
+ def _dumps(object, protocol):
+ return pickle.dumps(object, bin=protocol)
class DictMixin: pass
+
from . import db
_unspecified = object()
@@ -87,7 +97,10 @@ class DBShelf(DictMixin):
def __init__(self, dbenv=None):
self.db = db.DB(dbenv)
self._closed = True
- self.binary = 1
+ if HIGHEST_PROTOCOL:
+ self.protocol = HIGHEST_PROTOCOL
+ else:
+ self.protocol = 1
def __del__(self):
@@ -114,7 +127,7 @@ class DBShelf(DictMixin):
def __setitem__(self, key, value):
- data = pickle.dumps(value, self.binary)
+ data = _dumps(value, self.protocol)
self.db[key] = data
@@ -169,7 +182,7 @@ class DBShelf(DictMixin):
# Other methods
def __append(self, value, txn=None):
- data = pickle.dumps(value, self.binary)
+ data = _dumps(value, self.protocol)
return self.db.append(data, txn)
def append(self, value, txn=None):
@@ -200,19 +213,19 @@ class DBShelf(DictMixin):
return pickle.loads(data)
def get_both(self, key, value, txn=None, flags=0):
- data = pickle.dumps(value, self.binary)
+ data = _dumps(value, self.protocol)
data = self.db.get(key, data, txn, flags)
return pickle.loads(data)
def cursor(self, txn=None, flags=0):
c = DBShelfCursor(self.db.cursor(txn, flags))
- c.binary = self.binary
+ c.protocol = self.protocol
return c
def put(self, key, value, txn=None, flags=0):
- data = pickle.dumps(value, self.binary)
+ data = _dumps(value, self.protocol)
return self.db.put(key, data, txn, flags)
@@ -252,11 +265,13 @@ class DBShelfCursor:
#----------------------------------------------
def dup(self, flags=0):
- return DBShelfCursor(self.dbc.dup(flags))
+ c = DBShelfCursor(self.dbc.dup(flags))
+ c.protocol = self.protocol
+ return c
def put(self, key, value, flags=0):
- data = pickle.dumps(value, self.binary)
+ data = _dumps(value, self.protocol)
return self.dbc.put(key, data, flags)
@@ -274,7 +289,7 @@ class DBShelfCursor:
return self._extract(rec)
def get_3(self, key, value, flags):
- data = pickle.dumps(value, self.binary)
+ data = _dumps(value, self.protocol)
rec = self.dbc.get(key, flags)
return self._extract(rec)
@@ -291,7 +306,7 @@ class DBShelfCursor:
def get_both(self, key, value, flags=0):
- data = pickle.dumps(value, self.binary)
+ data = _dumps(value, self.protocol)
rec = self.dbc.get_both(key, flags)
return self._extract(rec)
diff --git a/Lib/bsddb/test/test_misc.py b/Lib/bsddb/test/test_misc.py
index 15098b7..5223180 100644
--- a/Lib/bsddb/test/test_misc.py
+++ b/Lib/bsddb/test/test_misc.py
@@ -28,10 +28,10 @@ class MiscTestCase(unittest.TestCase):
pass
shutil.rmtree(self.homeDir)
- def test01_badpointer(self):
- dbs = dbshelve.open(self.filename)
- dbs.close()
- self.assertRaises(db.DBError, dbs.get, "foo")
+## def test01_badpointer(self):
+## dbs = dbshelve.open(self.filename)
+## dbs.close()
+## self.assertRaises(db.DBError, dbs.get, "foo")
def test02_db_home(self):
env = db.DBEnv()
@@ -46,6 +46,26 @@ class MiscTestCase(unittest.TestCase):
rp = repr(db)
self.assertEquals(rp, "{}")
+ # http://sourceforge.net/tracker/index.php?func=detail&aid=1708868&group_id=13900&atid=313900
+ #
+ # See the bug report for details.
+ #
+ # The problem was that make_key_dbt() was not allocating a copy of
+ # string keys but FREE_DBT() was always being told to free it when the
+ # database was opened with DB_THREAD.
+## def test04_double_free_make_key_dbt(self):
+## try:
+## db1 = db.DB()
+## db1.open(self.filename, None, db.DB_BTREE,
+## db.DB_CREATE | db.DB_THREAD)
+
+## curs = db1.cursor()
+## t = curs.get(b"/foo", db.DB_SET)
+## # double free happened during exit from DBC_get
+## finally:
+## db1.close()
+## os.unlink(self.filename)
+
#----------------------------------------------------------------------