summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDong-hee Na <donghee.na@python.org>2023-07-23 14:26:23 (GMT)
committerGitHub <noreply@github.com>2023-07-23 14:26:23 (GMT)
commit0ae4870d09de82ed5063b6998c172cc63628437e (patch)
tree467aa07b0291a44a37ea9de2654c60ff9464ffcb
parentb3c34e55c053846beb35f5e4253ef237b3494bd0 (diff)
downloadcpython-0ae4870d09de82ed5063b6998c172cc63628437e.zip
cpython-0ae4870d09de82ed5063b6998c172cc63628437e.tar.gz
cpython-0ae4870d09de82ed5063b6998c172cc63628437e.tar.bz2
gh-107122: Add clear method to dbm.ndbm module (gh-107126)
-rw-r--r--Doc/library/dbm.rst6
-rw-r--r--Lib/test/test_dbm.py15
-rw-r--r--Lib/test/test_dbm_ndbm.py13
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst1
-rw-r--r--Modules/_dbmmodule.c33
-rw-r--r--Modules/clinic/_dbmmodule.c.h24
6 files changed, 91 insertions, 1 deletions
diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst
index d226fa9..766847b 100644
--- a/Doc/library/dbm.rst
+++ b/Doc/library/dbm.rst
@@ -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
-----------------------------------------------
diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py
index f21eebc..e3924d8 100644
--- a/Lib/test/test_dbm.py
+++ b/Lib/test/test_dbm.py
@@ -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
diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py
index 8f37e3c..e0f31c9 100644
--- a/Lib/test/test_dbm_ndbm.py
+++ b/Lib/test/test_dbm_ndbm.py
@@ -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()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst
new file mode 100644
index 0000000..d63aeb5
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst
@@ -0,0 +1 @@
+Add :meth:`dbm.ndbm.clear` to :mod:`dbm.ndbm`. Patch By Dong-hee Na.
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c
index 5be444d..bd80769 100644
--- a/Modules/_dbmmodule.c
+++ b/Modules/_dbmmodule.c
@@ -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 */
diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h
index 172dc4b..98aac07 100644
--- a/Modules/clinic/_dbmmodule.c.h
+++ b/Modules/clinic/_dbmmodule.c.h
@@ -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]*/