From 7a930a7fadabaecefab8a1679107b610a5c15bfe Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 23 Jul 2023 21:24:10 +0900 Subject: [PATCH 1/7] gh-107122: Add clear method to dbm.ndbm module --- Doc/library/dbm.rst | 5 ++++ Lib/test/test_dbm.py | 15 ++++++++++ ...-07-23-21-16-54.gh-issue-107122.VNuNcq.rst | 1 + Modules/_dbmmodule.c | 29 +++++++++++++++++++ Modules/clinic/_dbmmodule.c.h | 24 ++++++++++++++- 5 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index d226fa9f962cb4..f4ea92198f07c9 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -320,6 +320,11 @@ 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 f21eebc6530c76..e3924d8ec8b5c1 100644 --- a/Lib/test/test_dbm.py +++ b/Lib/test/test_dbm.py @@ -155,6 +155,21 @@ def test_keys(self): 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/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 00000000000000..8beaf51316762c --- /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:`clear` to :mod:`dbm.ndbm`. Patch By Dong-hee Na. diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 5be444d53e8da3..3cb2e55eb98c3f 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -414,6 +414,34 @@ _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); + for (datum key = dbm_firstkey(self->di_dbm); key.dptr; key = dbm_nextkey(self->di_dbm)) { + 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; + } + } + if (self->di_size > 0) { + self->di_size = 0; + } + Py_RETURN_NONE; +} + static PyObject * dbm__enter__(PyObject *self, PyObject *args) { @@ -431,6 +459,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 172dc4b9d5793e..98aac07423c8ab 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -138,6 +138,28 @@ _dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, P 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 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=28dcf736654137c2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b3053c67ecfcc29c input=a9049054013a1b77]*/ From d0f930c0cf3bd682a8f52b0fbd7e8408cb91993c Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 23 Jul 2023 21:36:02 +0900 Subject: [PATCH 2/7] Address code review --- Modules/_dbmmodule.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 3cb2e55eb98c3f..a8bec6c142f05e 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -435,9 +435,9 @@ _dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls) PyErr_SetString(state->dbm_error, "cannot delete item from database"); return NULL; } - } - if (self->di_size > 0) { - self->di_size = 0; + if (self->di_size > 0) { + self->di_size--; + } } Py_RETURN_NONE; } From 7a7e8266c53e9b55185d3e1424dcb9bb379dd081 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 23 Jul 2023 21:40:34 +0900 Subject: [PATCH 3/7] Be more safer --- Modules/_dbmmodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index a8bec6c142f05e..c01a73be5769f2 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -429,7 +429,8 @@ _dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls) _dbm_state *state = PyType_GetModuleState(cls); assert(state != NULL); check_dbmobject_open(self, state->dbm_error); - for (datum key = dbm_firstkey(self->di_dbm); key.dptr; key = dbm_nextkey(self->di_dbm)) { + datum key; + while (key = dbm_firstkey(self->di_dbm), key.dptr) { if (dbm_delete(self->di_dbm, key) < 0) { dbm_clearerr(self->di_dbm); PyErr_SetString(state->dbm_error, "cannot delete item from database"); From 3affdb7feadcd9962e462191029a166eca661bcd Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 23 Jul 2023 21:46:44 +0900 Subject: [PATCH 4/7] Address code review --- Modules/_dbmmodule.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index c01a73be5769f2..6ea4b7f1e9b43a 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -430,7 +430,11 @@ _dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls) assert(state != NULL); check_dbmobject_open(self, state->dbm_error); datum key; - while (key = dbm_firstkey(self->di_dbm), key.dptr) { + 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"); From 2be5402780b48476219c6024455393c11dd96ca8 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 23 Jul 2023 22:01:36 +0900 Subject: [PATCH 5/7] Update test_dbm_ndbm --- Lib/test/test_dbm_ndbm.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py index 8f37e3cc624e2e..e0f31c9a9a337d 100644 --- a/Lib/test/test_dbm_ndbm.py +++ b/Lib/test/test_dbm_ndbm.py @@ -147,6 +147,19 @@ def test_bool_on_closed_db_raises(self): 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() From 1d1444078097c0af3c3cbe4d86b625e6316a3793 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 23 Jul 2023 22:11:24 +0900 Subject: [PATCH 6/7] Update docs --- Doc/library/dbm.rst | 1 + .../2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index f4ea92198f07c9..766847b971b645 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -321,6 +321,7 @@ 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 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 index 8beaf51316762c..d63aeb54ae1454 100644 --- 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 @@ -1 +1 @@ -Add :meth:`clear` to :mod:`dbm.ndbm`. Patch By Dong-hee Na. +Add :meth:`dbm.ndbm.clear` to :mod:`dbm.ndbm`. Patch By Dong-hee Na. From 5eb2b1305376d5204391d14f0e4ae213aa8fdaae Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 23 Jul 2023 22:19:15 +0900 Subject: [PATCH 7/7] Simply invalidate cache --- Modules/_dbmmodule.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 6ea4b7f1e9b43a..bd807698927e86 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -430,6 +430,8 @@ _dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *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) { @@ -440,9 +442,6 @@ _dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls) PyErr_SetString(state->dbm_error, "cannot delete item from database"); return NULL; } - if (self->di_size > 0) { - self->di_size--; - } } Py_RETURN_NONE; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy