diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2007-08-05 15:39:16 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2007-08-05 15:39:16 (GMT) |
commit | 64ce5052e1c2495bcbc78f732e8ece2f4c8375ac (patch) | |
tree | be92ddb8c857ddb4a0cd06439c025243d71ad403 /Lib | |
parent | 33d2689fc900a814f0a7d2f846abe0c34024ae17 (diff) | |
download | cpython-64ce5052e1c2495bcbc78f732e8ece2f4c8375ac.zip cpython-64ce5052e1c2495bcbc78f732e8ece2f4c8375ac.tar.gz cpython-64ce5052e1c2495bcbc78f732e8ece2f4c8375ac.tar.bz2 |
Make bsddb use bytes as keys and values. Add StringKeys
and StringValues classes. Fix test suite.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/bsddb/__init__.py | 150 | ||||
-rwxr-xr-x | Lib/test/test_bsddb.py | 8 |
2 files changed, 142 insertions, 16 deletions
diff --git a/Lib/bsddb/__init__.py b/Lib/bsddb/__init__.py index 02df499..6225304 100644 --- a/Lib/bsddb/__init__.py +++ b/Lib/bsddb/__init__.py @@ -64,15 +64,9 @@ error = db.DBError # So bsddb.error will mean something... #---------------------------------------------------------------------- -import sys, os - -# for backwards compatibility with python versions older than 2.3, the -# iterator interface is dynamically defined and added using a mixin -# class. old python can't tokenize it due to the yield keyword. -if sys.version >= '2.3': - import UserDict - from weakref import ref - exec(""" +import sys, os, UserDict +from weakref import ref + class _iter_mixin(UserDict.DictMixin): def _make_iter_cursor(self): cur = _DeadlockWrap(self.db.cursor) @@ -145,10 +139,6 @@ class _iter_mixin(UserDict.DictMixin): except _bsddb.DBCursorClosedError: # the database was modified during iteration. abort. return -""") -else: - class _iter_mixin: pass - class _DBWithCursor(_iter_mixin): """ @@ -290,6 +280,138 @@ class _DBWithCursor(_iter_mixin): self._checkOpen() return _DeadlockWrap(self.db.sync) +class _ExposedProperties: + @property + def _cursor_refs(self): + return self.db._cursor_refs + +class StringKeys(UserDict.DictMixin, _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 sync(self): + return self.db.sync() + +class StringValues(UserDict.DictMixin, _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].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 sync(self): + return self.db.sync() + #---------------------------------------------------------------------- # Compatibility object factory functions @@ -375,7 +497,7 @@ def _checkflag(flag, file): if file is not None and os.path.isfile(file): os.unlink(file) else: - raise error, "flags should be one of 'r', 'w', 'c' or 'n'" + raise error, "flags should be one of 'r', 'w', 'c' or 'n', not "+repr(flag) return flags | db.DB_THREAD #---------------------------------------------------------------------- diff --git a/Lib/test/test_bsddb.py b/Lib/test/test_bsddb.py index 7413307..2da40453 100755 --- a/Lib/test/test_bsddb.py +++ b/Lib/test/test_bsddb.py @@ -12,8 +12,12 @@ from test import test_support class TestBSDDB(unittest.TestCase): openflag = 'c' + def do_open(self, *args, **kw): + # openmethod is a list so that it's not mistaken as an instance method + return bsddb.StringValues(bsddb.StringKeys(self.openmethod[0](*args, **kw))) + def setUp(self): - self.f = self.openmethod[0](self.fname, self.openflag, cachesize=32768) + self.f = self.do_open(self.fname, self.openflag, cachesize=32768) self.d = dict(q='Guido', w='van', e='Rossum', r='invented', t='Python', y='') for k, v in self.d.items(): self.f[k] = v @@ -47,7 +51,7 @@ class TestBSDDB(unittest.TestCase): # so finish here. return self.f.close() - self.f = self.openmethod[0](self.fname, 'w') + self.f = self.do_open(self.fname, 'w') for k, v in self.d.items(): self.assertEqual(self.f[k], v) |