diff -r 61463ff7dc68 Lib/dbm/dumb.py --- a/Lib/dbm/dumb.py Wed Oct 23 22:03:45 2013 +0200 +++ b/Lib/dbm/dumb.py Fri Oct 25 09:39:35 2013 +0300 @@ -118,7 +118,12 @@ sync = _commit + def _check_closed(self): + if self._index is None: + raise error('DBM object has already been closed') + def __getitem__(self, key): + self._check_closed() if isinstance(key, str): key = key.encode('utf-8') pos, siz = self._index[key] # may raise KeyError @@ -165,6 +170,7 @@ f.close() def __setitem__(self, key, val): + self._check_closed() if isinstance(key, str): key = key.encode('utf-8') elif not isinstance(key, (bytes, bytearray)): @@ -198,6 +204,7 @@ # (so that _commit() never gets called). def __delitem__(self, key): + self._check_closed() if isinstance(key, str): key = key.encode('utf-8') # The blocks used by the associated value are lost. @@ -209,21 +216,26 @@ self._commit() def keys(self): + self._check_closed() return list(self._index.keys()) def items(self): + self._check_closed() return [(key, self[key]) for key in self._index.keys()] def __contains__(self, key): + self._check_closed() if isinstance(key, str): key = key.encode('utf-8') return key in self._index def iterkeys(self): + self._check_closed() return iter(self._index.keys()) __iter__ = iterkeys def __len__(self): + self._check_closed() return len(self._index) def close(self): diff -r 61463ff7dc68 Lib/test/test_dbm_dumb.py --- a/Lib/test/test_dbm_dumb.py Wed Oct 23 22:03:45 2013 +0200 +++ b/Lib/test/test_dbm_dumb.py Fri Oct 25 09:39:35 2013 +0300 @@ -8,6 +8,8 @@ import unittest import dbm.dumb as dumbdbm from test import support +import operator +from functools import partial _fname = support.TESTFN @@ -186,6 +188,23 @@ self.assertEqual(expected, got) f.close() + def test_check_closed(self): + f = dumbdbm.open(_fname, 'c') + f.close() + + for meth in (partial(operator.delitem, f), + partial(operator.setitem, f, 'b'), + partial(operator.getitem, f), + partial(operator.contains, f), + operator.methodcaller('keys'), + operator.methodcaller('iterkeys'), + operator.methodcaller('items'), + len): + with self.assertRaises(dumbdbm.error) as cm: + meth(f) + self.assertEqual(str(cm.exception), + "DBM object has already been closed") + def tearDown(self): _delete_files()