gh-107122: Add clear method to dbm.ndbm module (gh-107126)

This commit is contained in:
Dong-hee Na 2023-07-23 23:26:23 +09:00 committed by GitHub
parent b3c34e55c0
commit 0ae4870d09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 91 additions and 1 deletions

View File

@ -320,6 +320,12 @@ to locate the appropriate header file to simplify building this module.
Close the ``ndbm`` database.
.. method:: ndbm.clear()
Remove all items from the ``ndbm`` database.
.. versionadded:: 3.13
:mod:`dbm.dumb` --- Portable DBM implementation
-----------------------------------------------

View File

@ -155,6 +155,21 @@ class AnyDBMTestCase:
self.assertNotIn(b'xxx', d)
self.assertRaises(KeyError, lambda: d[b'xxx'])
def test_clear(self):
with dbm.open(_fname, 'c') as d:
self.assertEqual(d.keys(), [])
a = [(b'a', b'b'), (b'12345678910', b'019237410982340912840198242')]
for k, v in a:
d[k] = v
for k, _ in a:
self.assertIn(k, d)
self.assertEqual(len(d), len(a))
d.clear()
self.assertEqual(len(d), 0)
for k, _ in a:
self.assertNotIn(k, d)
def setUp(self):
self.addCleanup(setattr, dbm, '_defaultmod', dbm._defaultmod)
dbm._defaultmod = self.module

View File

@ -147,6 +147,19 @@ class DbmTestCase(unittest.TestCase):
db['a'] = 'b'
self.assertRaises(dbm.ndbm.error, bool, db)
def test_clear(self):
kvs = [('foo', 'bar'), ('1234', '5678')]
with dbm.ndbm.open(self.filename, 'c') as db:
for k, v in kvs:
db[k] = v
self.assertIn(k, db)
self.assertEqual(len(db), len(kvs))
db.clear()
for k, v in kvs:
self.assertNotIn(k, db)
self.assertEqual(len(db), 0)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1 @@
Add :meth:`dbm.ndbm.clear` to :mod:`dbm.ndbm`. Patch By Dong-hee Na.

View File

@ -414,6 +414,38 @@ _dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key,
return default_value;
}
/*[clinic input]
_dbm.dbm.clear
cls: defining_class
/
Remove all items from the database.
[clinic start generated code]*/
static PyObject *
_dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls)
/*[clinic end generated code: output=8d126b9e1d01a434 input=43aa6ca1acb7f5f5]*/
{
_dbm_state *state = PyType_GetModuleState(cls);
assert(state != NULL);
check_dbmobject_open(self, state->dbm_error);
datum key;
// Invalidate cache
self->di_size = -1;
while (1) {
key = dbm_firstkey(self->di_dbm);
if (key.dptr == NULL) {
break;
}
if (dbm_delete(self->di_dbm, key) < 0) {
dbm_clearerr(self->di_dbm);
PyErr_SetString(state->dbm_error, "cannot delete item from database");
return NULL;
}
}
Py_RETURN_NONE;
}
static PyObject *
dbm__enter__(PyObject *self, PyObject *args)
{
@ -431,6 +463,7 @@ static PyMethodDef dbm_methods[] = {
_DBM_DBM_KEYS_METHODDEF
_DBM_DBM_GET_METHODDEF
_DBM_DBM_SETDEFAULT_METHODDEF
_DBM_DBM_CLEAR_METHODDEF
{"__enter__", dbm__enter__, METH_NOARGS, NULL},
{"__exit__", dbm__exit__, METH_VARARGS, NULL},
{NULL, NULL} /* sentinel */

View File

@ -138,6 +138,28 @@ exit:
return return_value;
}
PyDoc_STRVAR(_dbm_dbm_clear__doc__,
"clear($self, /)\n"
"--\n"
"\n"
"Remove all items from the database.");
#define _DBM_DBM_CLEAR_METHODDEF \
{"clear", _PyCFunction_CAST(_dbm_dbm_clear), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_clear__doc__},
static PyObject *
_dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls);
static PyObject *
_dbm_dbm_clear(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
if (nargs) {
PyErr_SetString(PyExc_TypeError, "clear() takes no arguments");
return NULL;
}
return _dbm_dbm_clear_impl(self, cls);
}
PyDoc_STRVAR(dbmopen__doc__,
"open($module, filename, flags=\'r\', mode=0o666, /)\n"
"--\n"
@ -200,4 +222,4 @@ skip_optional:
exit:
return return_value;
}
/*[clinic end generated code: output=28dcf736654137c2 input=a9049054013a1b77]*/
/*[clinic end generated code: output=b3053c67ecfcc29c input=a9049054013a1b77]*/