mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
Fix bsddb.db.DBError derived exceptions so they can be unpickled.
Also adds some backwards compatibility when compiling _bsddb.c on earlier python versions (needed for pybsddb).
This commit is contained in:
parent
795246cf99
commit
7f5b6f4b33
4 changed files with 100 additions and 6 deletions
|
|
@ -65,6 +65,7 @@ def suite():
|
|||
'test_join',
|
||||
'test_lock',
|
||||
'test_misc',
|
||||
'test_pickle',
|
||||
'test_queue',
|
||||
'test_recno',
|
||||
'test_thread',
|
||||
|
|
|
|||
75
Lib/bsddb/test/test_pickle.py
Normal file
75
Lib/bsddb/test/test_pickle.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
import sys, os, string
|
||||
import pickle
|
||||
try:
|
||||
import cPickle
|
||||
except ImportError:
|
||||
cPickle = None
|
||||
import unittest
|
||||
import glob
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError, e:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class pickleTestCase(unittest.TestCase):
|
||||
"""Verify that DBError can be pickled and unpickled"""
|
||||
db_home = 'db_home'
|
||||
db_name = 'test-dbobj.db'
|
||||
|
||||
def setUp(self):
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try: os.mkdir(homeDir)
|
||||
except os.error: pass
|
||||
|
||||
def tearDown(self):
|
||||
if hasattr(self, 'db'):
|
||||
del self.db
|
||||
if hasattr(self, 'env'):
|
||||
del self.env
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
def _base_test_pickle_DBError(self, pickle):
|
||||
self.env = db.DBEnv()
|
||||
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
|
||||
self.db = db.DB(self.env)
|
||||
self.db.open(self.db_name, db.DB_HASH, db.DB_CREATE)
|
||||
self.db.put('spam', 'eggs')
|
||||
assert self.db['spam'] == 'eggs'
|
||||
try:
|
||||
self.db.put('spam', 'ham', flags=db.DB_NOOVERWRITE)
|
||||
except db.DBError, egg:
|
||||
pickledEgg = pickle.dumps(egg)
|
||||
#print repr(pickledEgg)
|
||||
rottenEgg = pickle.loads(pickledEgg)
|
||||
if rottenEgg.args != egg.args or type(rottenEgg) != type(egg):
|
||||
raise Exception, (rottenEgg, '!=', egg)
|
||||
else:
|
||||
raise Exception, "where's my DBError exception?!?"
|
||||
|
||||
self.db.close()
|
||||
self.env.close()
|
||||
|
||||
def test01_pickle_DBError(self):
|
||||
self._base_test_pickle_DBError(pickle=pickle)
|
||||
|
||||
if cPickle:
|
||||
def test02_cPickle_DBError(self):
|
||||
self._base_test_pickle_DBError(pickle=cPickle)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(pickleTestCase)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
||||
|
|
@ -15,6 +15,8 @@ Core and builtins
|
|||
Extension Modules
|
||||
-----------------
|
||||
|
||||
- Fix bsddb.db.DBError derived exceptions so they can be unpickled.
|
||||
|
||||
Library
|
||||
-------
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,10 @@
|
|||
static char *rcs_id = "$Id$";
|
||||
|
||||
|
||||
#if (PY_VERSION_HEX < 0x02050000)
|
||||
#define Py_ssize_t int
|
||||
#endif
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
|
||||
/* These are for when calling Python --> C */
|
||||
|
|
@ -4688,7 +4692,11 @@ static PyMethodDef DB_methods[] = {
|
|||
|
||||
|
||||
static PyMappingMethods DB_mapping = {
|
||||
#if (PY_VERSION_HEX < 0x02050000)
|
||||
(inquiry)DB_length, /*mp_length*/
|
||||
#else
|
||||
(lenfunc)DB_length, /*mp_length*/
|
||||
#endif
|
||||
(binaryfunc)DB_subscript, /*mp_subscript*/
|
||||
(objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
|
||||
};
|
||||
|
|
@ -5385,9 +5393,21 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
ADD_INT(d, DB_SET_TXN_TIMEOUT);
|
||||
#endif
|
||||
|
||||
/* The exception name must be correct for pickled exception *
|
||||
* objects to unpickle properly. */
|
||||
#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
|
||||
#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
|
||||
#else
|
||||
#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
|
||||
#endif
|
||||
|
||||
/* All the rest of the exceptions derive only from DBError */
|
||||
#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
|
||||
PyDict_SetItemString(d, #name, name)
|
||||
|
||||
/* The base exception class is DBError */
|
||||
DBError = PyErr_NewException("bsddb._db.DBError", NULL, NULL);
|
||||
PyDict_SetItemString(d, "DBError", DBError);
|
||||
DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
|
||||
MAKE_EX(DBError);
|
||||
|
||||
/* Some magic to make DBNotFoundError and DBKeyEmptyError derive
|
||||
* from both DBError and KeyError, since the API only supports
|
||||
|
|
@ -5401,10 +5421,6 @@ DL_EXPORT(void) init_bsddb(void)
|
|||
PyDict_DelItemString(d, "KeyError");
|
||||
|
||||
|
||||
/* All the rest of the exceptions derive only from DBError */
|
||||
#define MAKE_EX(name) name = PyErr_NewException("bsddb._db." #name, DBError, NULL); \
|
||||
PyDict_SetItemString(d, #name, name)
|
||||
|
||||
#if !INCOMPLETE_IS_WARNING
|
||||
MAKE_EX(DBIncompleteError);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue