#6045: provide at least get() and setdefault() for all dbm modules.
This commit is contained in:
parent
da72231c9f
commit
d9e833c70a
|
@ -61,10 +61,15 @@ the Oracle Berkeley DB.
|
|||
modified by the prevailing umask).
|
||||
|
||||
|
||||
The object returned by :func:`.open` supports most of the same functionality as
|
||||
The object returned by :func:`.open` supports the same basic functionality as
|
||||
dictionaries; keys and their corresponding values can be stored, retrieved, and
|
||||
deleted, and the :keyword:`in` operator and the :meth:`keys` method are
|
||||
available. Key and values are always stored as bytes. This means that when
|
||||
available, as well as :meth:`get` and :meth:`setdefault`.
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
:meth:`get` and :meth:`setdefault` are now available in all database modules.
|
||||
|
||||
Key and values are always stored as bytes. This means that when
|
||||
strings are used they are implicitly converted to the default encoding before
|
||||
being stored.
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ class _Database(collections.MutableMapping):
|
|||
# The blocks used by the associated value are lost.
|
||||
del self._index[key]
|
||||
# XXX It's unclear why we do a _commit() here (the code always
|
||||
# XXX has, so I'm not changing it). _setitem__ doesn't try to
|
||||
# XXX has, so I'm not changing it). __setitem__ doesn't try to
|
||||
# XXX keep the directory file in synch. Why should we? Or
|
||||
# XXX why shouldn't __setitem__?
|
||||
self._commit()
|
||||
|
@ -232,7 +232,7 @@ class _Database(collections.MutableMapping):
|
|||
|
||||
__del__ = close
|
||||
|
||||
def _chmod (self, file):
|
||||
def _chmod(self, file):
|
||||
if hasattr(self._os, 'chmod'):
|
||||
self._os.chmod(file, self._mode)
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@ class TestGdbm(unittest.TestCase):
|
|||
key_set.remove(key)
|
||||
key = self.g.nextkey(key)
|
||||
self.assertRaises(KeyError, lambda: self.g['xxx'])
|
||||
# get() and setdefault() work as in the dict interface
|
||||
self.assertEqual(self.g.get(b'xxx', b'foo'), b'foo')
|
||||
self.assertEqual(self.g.setdefault(b'xxx', b'foo'), b'foo')
|
||||
self.assertEqual(self.g[b'xxx'], b'foo')
|
||||
|
||||
def test_error_conditions(self):
|
||||
# Try to open a non-existent database.
|
||||
|
|
|
@ -37,7 +37,9 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue 10620: `python -m unittest` can accept file paths instead of module
|
||||
- Issue #6045: dbm.gnu databases now support get() and setdefault() methods.
|
||||
|
||||
- Issue #10620: `python -m unittest` can accept file paths instead of module
|
||||
names for running specific tests.
|
||||
|
||||
- Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`,
|
||||
|
|
|
@ -135,6 +135,28 @@ dbm_subscript(dbmobject *dp, register PyObject *key)
|
|||
return v;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(dbm_get__doc__,
|
||||
"get(key[, default]) -> value\n\
|
||||
Get the value for key, or default if not present; if not given,\n\
|
||||
default is None.");
|
||||
|
||||
static PyObject *
|
||||
dbm_get(dbmobject *dp, PyObject *args)
|
||||
{
|
||||
PyObject *v, *res;
|
||||
PyObject *def = Py_None;
|
||||
|
||||
if (!PyArg_UnpackTuple(args, "get", 1, 2, &v, &def))
|
||||
return NULL;
|
||||
res = dbm_subscript(dp, v);
|
||||
if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||
PyErr_Clear();
|
||||
Py_INCREF(def);
|
||||
return def;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
|
||||
{
|
||||
|
@ -176,6 +198,29 @@ dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
|
|||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(dbm_setdefault__doc__,
|
||||
"setdefault(key[, default]) -> value\n\
|
||||
Get value for key, or set it to default and return default if not present;\n\
|
||||
if not given, default is None.");
|
||||
|
||||
static PyObject *
|
||||
dbm_setdefault(dbmobject *dp, PyObject *args)
|
||||
{
|
||||
PyObject *v, *res;
|
||||
PyObject *def = Py_None;
|
||||
|
||||
if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &v, &def))
|
||||
return NULL;
|
||||
res = dbm_subscript(dp, v);
|
||||
if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||
PyErr_Clear();
|
||||
if (dbm_ass_sub(dp, v, def) < 0)
|
||||
return NULL;
|
||||
return dbm_subscript(dp, v);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyMappingMethods dbm_as_mapping = {
|
||||
(lenfunc)dbm_length, /*mp_length*/
|
||||
(binaryfunc)dbm_subscript, /*mp_subscript*/
|
||||
|
@ -378,6 +423,8 @@ static PyMethodDef dbm_methods[] = {
|
|||
{"nextkey", (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__},
|
||||
{"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__},
|
||||
{"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__doc__},
|
||||
{"get", (PyCFunction)dbm_get, METH_VARARGS, dbm_get__doc__},
|
||||
{"setdefault",(PyCFunction)dbm_setdefault,METH_VARARGS, dbm_setdefault__doc__},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue