Skip to content

Commit 8f548c7

Browse files
committed
Add tests, and make the messages more similar
1 parent efd9cac commit 8f548c7

4 files changed

Lines changed: 51 additions & 13 deletions

File tree

Lib/test/test_dbm_gnu.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,25 @@ def test_localized_error(self):
217217
create_empty_file(os.path.join(d, 'test'))
218218
self.assertRaises(gdbm.error, gdbm.open, filename, 'r')
219219

220+
def test_type_errors(self):
221+
self.g = gdbm.open(filename, 'c')
222+
with self.assertRaisesRegex(
223+
TypeError, "^a bytes-like object is required, not 'int'$",
224+
):
225+
self.g[123]
226+
with self.assertRaisesRegex(
227+
TypeError, "^gdbm key must be bytes or str, not 'int'$",
228+
):
229+
123 in self.g
230+
with self.assertRaisesRegex(
231+
TypeError, "^gdbm key must be bytes or str, not 'NoneType'$",
232+
):
233+
self.g[None] = 123
234+
with self.assertRaisesRegex(
235+
TypeError, "^gdbm value must be bytes or str, not 'int'$",
236+
):
237+
self.g['foo'] = 123
238+
220239

221240
if __name__ == '__main__':
222241
unittest.main()

Lib/test/test_dbm_ndbm.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,25 @@ def test_clear(self):
160160
self.assertNotIn(k, db)
161161
self.assertEqual(len(db), 0)
162162

163+
def test_type_errors(self):
164+
with dbm.ndbm.open(self.filename, 'c') as db:
165+
with self.assertRaisesRegex(
166+
TypeError, "^a bytes-like object is required, not 'int'$",
167+
):
168+
db[123]
169+
with self.assertRaisesRegex(
170+
TypeError, "^dbm key must be bytes or str, not 'int'$",
171+
):
172+
123 in db
173+
with self.assertRaisesRegex(
174+
TypeError, "^dbm key must be bytes or str, not 'NoneType'$",
175+
):
176+
db[None] = 123
177+
with self.assertRaisesRegex(
178+
TypeError, "^dbm value must be bytes or str, not 'int'$",
179+
):
180+
db['foo'] = 123
181+
163182

164183
if __name__ == '__main__':
165184
unittest.main()

Modules/_dbmmodule.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ dbm_ass_sub_lock_held(PyObject *self, PyObject *v, PyObject *w)
232232

233233
if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) {
234234
PyErr_Format(PyExc_TypeError,
235-
"database keys must be bytes or str, not %T",
235+
"dbm key must be bytes or str, not '%T'",
236236
v);
237237
return -1;
238238
}
@@ -260,7 +260,7 @@ dbm_ass_sub_lock_held(PyObject *self, PyObject *v, PyObject *w)
260260
} else {
261261
if ( !PyArg_Parse(w, "s#", &drec.dptr, &tmp_size) ) {
262262
PyErr_Format(PyExc_TypeError,
263-
"database values must be bytes or str, not %T",
263+
"dbm value must be bytes or str, not '%T'",
264264
w);
265265
return -1;
266266
}
@@ -371,8 +371,7 @@ dbm_contains_lock_held(PyObject *self, PyObject *arg)
371371
}
372372
else if (!PyBytes_Check(arg)) {
373373
PyErr_Format(PyExc_TypeError,
374-
"dbm key must be bytes or string, not %.100s",
375-
Py_TYPE(arg)->tp_name);
374+
"dbm key must be bytes or str, not '%T'", arg);
376375
return -1;
377376
}
378377
else {

Modules/_gdbmmodule.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,15 @@ gdbm_bool(PyObject *op)
237237
// This function is needed to support PY_SSIZE_T_CLEAN.
238238
// Return 1 on success, same to PyArg_Parse().
239239
static int
240-
parse_datum(PyObject *o, datum *d, const char *items_name)
240+
parse_datum(PyObject *o, datum *d, const char *item_name)
241241
{
242242
Py_ssize_t size;
243243
if (!PyArg_Parse(o, "s#", &d->dptr, &size)) {
244-
PyErr_Format(PyExc_TypeError,
245-
"database %s must be bytes or str, not %T",
246-
items_name, o);
244+
if (item_name) {
245+
PyErr_Format(PyExc_TypeError,
246+
"gdbm %s must be bytes or str, not '%T'",
247+
item_name, o);
248+
}
247249
return 0;
248250
}
249251
if (INT_MAX < size) {
@@ -262,7 +264,7 @@ gdbm_subscript_lock_held(PyObject *op, PyObject *key)
262264
gdbmobject *dp = _gdbmobject_CAST(op);
263265
_gdbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
264266

265-
if (!parse_datum(key, &krec, "keys")) {
267+
if (!parse_datum(key, &krec, NULL)) {
266268
return NULL;
267269
}
268270
if (dp->di_dbm == NULL) {
@@ -321,7 +323,7 @@ gdbm_ass_sub_lock_held(PyObject *op, PyObject *v, PyObject *w)
321323
gdbmobject *dp = _gdbmobject_CAST(op);
322324
_gdbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
323325

324-
if (!parse_datum(v, &krec, "keys")) {
326+
if (!parse_datum(v, &krec, "key")) {
325327
return -1;
326328
}
327329
if (dp->di_dbm == NULL) {
@@ -342,7 +344,7 @@ gdbm_ass_sub_lock_held(PyObject *op, PyObject *v, PyObject *w)
342344
}
343345
}
344346
else {
345-
if (!parse_datum(w, &drec, "values")) {
347+
if (!parse_datum(w, &drec, "value")) {
346348
return -1;
347349
}
348350
errno = 0;
@@ -490,8 +492,7 @@ gdbm_contains_lock_held(PyObject *self, PyObject *arg)
490492
}
491493
else if (!PyBytes_Check(arg)) {
492494
PyErr_Format(PyExc_TypeError,
493-
"gdbm key must be bytes or string, not %.100s",
494-
Py_TYPE(arg)->tp_name);
495+
"gdbm key must be bytes or str, not '%T'", arg);
495496
return -1;
496497
}
497498
else {

0 commit comments

Comments
 (0)