diff options
Diffstat (limited to 'Lib/dbm')
-rw-r--r-- | Lib/dbm/__init__.py | 16 | ||||
-rw-r--r-- | Lib/dbm/dumb.py | 47 |
2 files changed, 45 insertions, 18 deletions
diff --git a/Lib/dbm/__init__.py b/Lib/dbm/__init__.py index a783fde..5f4664a 100644 --- a/Lib/dbm/__init__.py +++ b/Lib/dbm/__init__.py @@ -42,7 +42,7 @@ _names = ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb'] _defaultmod = None _modules = {} -error = (error, IOError) +error = (error, OSError) try: from dbm import ndbm @@ -111,12 +111,10 @@ def whichdb(filename): try: f = io.open(filename + ".pag", "rb") f.close() - # dbm linked with gdbm on OS/2 doesn't have .dir file - if not (ndbm.library == "GNU gdbm" and sys.platform == "os2emx"): - f = io.open(filename + ".dir", "rb") - f.close() + f = io.open(filename + ".dir", "rb") + f.close() return "dbm.ndbm" - except IOError: + except OSError: # some dbm emulations based on Berkeley DB generate a .db file # some do not, but they should be caught by the bsd checks try: @@ -129,7 +127,7 @@ def whichdb(filename): d = ndbm.open(filename) d.close() return "dbm.ndbm" - except IOError: + except OSError: pass # Check for dumbdbm next -- this has a .dir and a .dat file @@ -146,13 +144,13 @@ def whichdb(filename): return "dbm.dumb" finally: f.close() - except (OSError, IOError): + except OSError: pass # See if the file exists, return None if not try: f = io.open(filename, "rb") - except IOError: + except OSError: return None # Read the start of the file -- the magic number diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py index cfb9123..17854ee 100644 --- a/Lib/dbm/dumb.py +++ b/Lib/dbm/dumb.py @@ -29,7 +29,7 @@ __all__ = ["error", "open"] _BLOCKSIZE = 512 -error = IOError +error = OSError class _Database(collections.MutableMapping): @@ -67,7 +67,7 @@ class _Database(collections.MutableMapping): # Mod by Jack: create data file if needed try: f = _io.open(self._datfile, 'r', encoding="Latin-1") - except IOError: + except OSError: f = _io.open(self._datfile, 'w', encoding="Latin-1") self._chmod(self._datfile) f.close() @@ -78,7 +78,7 @@ class _Database(collections.MutableMapping): self._index = {} try: f = _io.open(self._dirfile, 'r', encoding="Latin-1") - except IOError: + except OSError: pass else: for line in f: @@ -100,12 +100,12 @@ class _Database(collections.MutableMapping): try: self._os.unlink(self._bakfile) - except self._os.error: + except OSError: pass try: self._os.rename(self._dirfile, self._bakfile) - except self._os.error: + except OSError: pass f = self._io.open(self._dirfile, 'w', encoding="Latin-1") @@ -118,9 +118,14 @@ class _Database(collections.MutableMapping): sync = _commit + def _verify_open(self): + if self._index is None: + raise error('DBM object has already been closed') + def __getitem__(self, key): if isinstance(key, str): key = key.encode('utf-8') + self._verify_open() pos, siz = self._index[key] # may raise KeyError f = _io.open(self._datfile, 'rb') f.seek(pos) @@ -173,6 +178,7 @@ class _Database(collections.MutableMapping): val = val.encode('utf-8') elif not isinstance(val, (bytes, bytearray)): raise TypeError("values must be bytes or strings") + self._verify_open() if key not in self._index: self._addkey(key, self._addval(val)) else: @@ -200,6 +206,7 @@ class _Database(collections.MutableMapping): def __delitem__(self, key): if isinstance(key, str): key = key.encode('utf-8') + self._verify_open() # The blocks used by the associated value are lost. del self._index[key] # XXX It's unclear why we do a _commit() here (the code always @@ -209,22 +216,38 @@ class _Database(collections.MutableMapping): self._commit() def keys(self): - return list(self._index.keys()) + try: + return list(self._index) + except TypeError: + raise error('DBM object has already been closed') from None def items(self): + self._verify_open() return [(key, self[key]) for key in self._index.keys()] def __contains__(self, key): if isinstance(key, str): key = key.encode('utf-8') - return key in self._index + try: + return key in self._index + except TypeError: + if self._index is None: + raise error('DBM object has already been closed') from None + else: + raise def iterkeys(self): - return iter(self._index.keys()) + try: + return iter(self._index) + except TypeError: + raise error('DBM object has already been closed') from None __iter__ = iterkeys def __len__(self): - return len(self._index) + try: + return len(self._index) + except TypeError: + raise error('DBM object has already been closed') from None def close(self): self._commit() @@ -236,6 +259,12 @@ class _Database(collections.MutableMapping): if hasattr(self._os, 'chmod'): self._os.chmod(file, self._mode) + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + def open(file, flag=None, mode=0o666): """Open the database file, filename, and return corresponding object. |