Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b17acad

Browse files
committed
Make db modules' error classes inherit IOError.
Stop dbm from importing every dbm module when imported.
1 parent e81f5ef commit b17acad

5 files changed

Lines changed: 50 additions & 51 deletions

File tree

Lib/dbm/__init__.py

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,26 @@ class error(Exception):
4848
pass
4949

5050
_names = ['dbm.bsd', 'dbm.gnu', 'dbm.ndbm', 'dbm.dumb']
51-
_errors = [error]
5251
_defaultmod = None
5352
_modules = {}
5453

55-
for _name in _names:
56-
try:
57-
_mod = __import__(_name, fromlist=['open'])
58-
except ImportError:
59-
continue
60-
if not _defaultmod:
61-
_defaultmod = _mod
62-
_modules[_name] = _mod
63-
_errors.append(_mod.error)
64-
65-
if not _defaultmod:
66-
raise ImportError("no dbm clone found; tried %s" % _names)
67-
68-
error = tuple(_errors)
54+
error = (error, IOError)
6955

7056

7157
def open(file, flag = 'r', mode = 0o666):
58+
global _defaultmod
59+
if _defaultmod is None:
60+
for name in _names:
61+
try:
62+
mod = __import__(name, fromlist=['open'])
63+
except ImportError:
64+
continue
65+
if not _defaultmod:
66+
_defaultmod = mod
67+
_modules[name] = mod
68+
if not _defaultmod:
69+
raise ImportError("no dbm clone found; tried %s" % _names)
70+
7271
# guess the type of an existing database
7372
result = whichdb(file)
7473
if result is None:
@@ -81,19 +80,14 @@ def open(file, flag = 'r', mode = 0o666):
8180
elif result == "":
8281
# db type cannot be determined
8382
raise error("db type could not be determined")
83+
elif result not in _modules:
84+
raise error("db type is {0}, but the module is not "
85+
"available".format(result))
8486
else:
8587
mod = _modules[result]
8688
return mod.open(file, flag, mode)
8789

8890

89-
try:
90-
from dbm import ndbm
91-
_dbmerror = ndbm.error
92-
except ImportError:
93-
ndbm = None
94-
# just some sort of valid exception which might be raised in the ndbm test
95-
_dbmerror = IOError
96-
9791
def whichdb(filename):
9892
"""Guess which db package to use to open a db file.
9993
@@ -129,7 +123,7 @@ def whichdb(filename):
129123
d = ndbm.open(filename)
130124
d.close()
131125
return "dbm.ndbm"
132-
except (IOError, _dbmerror):
126+
except IOError:
133127
pass
134128

135129
# Check for dumbdbm next -- this has a .dir and a .dat file

Lib/dbm/bsd.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
__all__ = ["error", "open"]
66

7-
error = bsddb.error
7+
class error(bsddb.error, IOError):
8+
pass
89

910
def open(file, flag = 'r', mode=0o666):
1011
return bsddb.hashopen(file, flag, mode)

Lib/test/test_dbm.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
# setting dbm to use each in turn, and yielding that module
1515
#
1616
def dbm_iterator():
17-
old_default = dbm._defaultmod
18-
for module in dbm._modules.values():
19-
dbm._defaultmod = module
20-
yield module
21-
dbm._defaultmod = old_default
17+
for name in dbm._names:
18+
try:
19+
mod = __import__(name, fromlist=['open'])
20+
except ImportError:
21+
continue
22+
dbm._modules[name] = mod
23+
yield mod
2224

2325
#
2426
# Clean up all scratch databases we might have created during testing
@@ -40,8 +42,20 @@ class AnyDBMTestCase(unittest.TestCase):
4042
'g': b'intended',
4143
}
4244

43-
def __init__(self, *args):
44-
unittest.TestCase.__init__(self, *args)
45+
def init_db(self):
46+
f = dbm.open(_fname, 'n')
47+
for k in self._dict:
48+
f[k.encode("ascii")] = self._dict[k]
49+
f.close()
50+
51+
def keys_helper(self, f):
52+
keys = sorted(k.decode("ascii") for k in f.keys())
53+
dkeys = sorted(self._dict.keys())
54+
self.assertEqual(keys, dkeys)
55+
return keys
56+
57+
def test_error(self):
58+
self.assert_(issubclass(self.module.error, IOError))
4559

4660
def test_anydbm_creation(self):
4761
f = dbm.open(_fname, 'c')
@@ -83,22 +97,11 @@ def read_helper(self, f):
8397
for key in self._dict:
8498
self.assertEqual(self._dict[key], f[key.encode("ascii")])
8599

86-
def init_db(self):
87-
f = dbm.open(_fname, 'n')
88-
for k in self._dict:
89-
f[k.encode("ascii")] = self._dict[k]
90-
f.close()
91-
92-
def keys_helper(self, f):
93-
keys = sorted(k.decode("ascii") for k in f.keys())
94-
dkeys = sorted(self._dict.keys())
95-
self.assertEqual(keys, dkeys)
96-
return keys
97-
98100
def tearDown(self):
99101
delete_files()
100102

101103
def setUp(self):
104+
dbm._defaultmod = self.module
102105
delete_files()
103106

104107

@@ -137,11 +140,11 @@ def setUp(self):
137140

138141

139142
def test_main():
140-
try:
141-
for module in dbm_iterator():
142-
test.support.run_unittest(AnyDBMTestCase, WhichDBTestCase)
143-
finally:
144-
delete_files()
143+
classes = [WhichDBTestCase]
144+
for mod in dbm_iterator():
145+
classes.append(type("TestCase-" + mod.__name__, (AnyDBMTestCase,),
146+
{'module': mod}))
147+
test.support.run_unittest(*classes)
145148

146149
if __name__ == "__main__":
147150
test_main()

Modules/_dbmmodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@ init_dbm(void) {
401401
return;
402402
d = PyModule_GetDict(m);
403403
if (DbmError == NULL)
404-
DbmError = PyErr_NewException("_dbm.error", NULL, NULL);
404+
DbmError = PyErr_NewException("_dbm.error",
405+
PyExc_IOError, NULL);
405406
s = PyUnicode_FromString(which_dbm);
406407
if (s != NULL) {
407408
PyDict_SetItemString(d, "library", s);

Modules/_gdbmmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ init_gdbm(void) {
523523
if (m == NULL)
524524
return;
525525
d = PyModule_GetDict(m);
526-
DbmError = PyErr_NewException("_gdbm.error", NULL, NULL);
526+
DbmError = PyErr_NewException("_gdbm.error", PyExc_IOError, NULL);
527527
if (DbmError != NULL) {
528528
PyDict_SetItemString(d, "error", DbmError);
529529
s = PyUnicode_FromString(dbmmodule_open_flags);

0 commit comments

Comments
 (0)