#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).
|
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
|
dictionaries; keys and their corresponding values can be stored, retrieved, and
|
||||||
deleted, and the :keyword:`in` operator and the :meth:`keys` method are
|
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
|
strings are used they are implicitly converted to the default encoding before
|
||||||
being stored.
|
being stored.
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ class _Database(collections.MutableMapping):
|
||||||
# The blocks used by the associated value are lost.
|
# The blocks used by the associated value are lost.
|
||||||
del self._index[key]
|
del self._index[key]
|
||||||
# XXX It's unclear why we do a _commit() here (the code always
|
# 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 keep the directory file in synch. Why should we? Or
|
||||||
# XXX why shouldn't __setitem__?
|
# XXX why shouldn't __setitem__?
|
||||||
self._commit()
|
self._commit()
|
||||||
|
@ -232,7 +232,7 @@ class _Database(collections.MutableMapping):
|
||||||
|
|
||||||
__del__ = close
|
__del__ = close
|
||||||
|
|
||||||
def _chmod (self, file):
|
def _chmod(self, file):
|
||||||
if hasattr(self._os, 'chmod'):
|
if hasattr(self._os, 'chmod'):
|
||||||
self._os.chmod(file, self._mode)
|
self._os.chmod(file, self._mode)
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,10 @@ class TestGdbm(unittest.TestCase):
|
||||||
key_set.remove(key)
|
key_set.remove(key)
|
||||||
key = self.g.nextkey(key)
|
key = self.g.nextkey(key)
|
||||||
self.assertRaises(KeyError, lambda: self.g['xxx'])
|
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):
|
def test_error_conditions(self):
|
||||||
# Try to open a non-existent database.
|
# Try to open a non-existent database.
|
||||||
|
|
|
@ -37,7 +37,9 @@ Core and Builtins
|
||||||
Library
|
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.
|
names for running specific tests.
|
||||||
|
|
||||||
- Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`,
|
- Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`,
|
||||||
|
|
|
@ -135,6 +135,28 @@ dbm_subscript(dbmobject *dp, register PyObject *key)
|
||||||
return v;
|
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
|
static int
|
||||||
dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
|
dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
|
||||||
{
|
{
|
||||||
|
@ -176,6 +198,29 @@ dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
|
||||||
return 0;
|
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 = {
|
static PyMappingMethods dbm_as_mapping = {
|
||||||
(lenfunc)dbm_length, /*mp_length*/
|
(lenfunc)dbm_length, /*mp_length*/
|
||||||
(binaryfunc)dbm_subscript, /*mp_subscript*/
|
(binaryfunc)dbm_subscript, /*mp_subscript*/
|
||||||
|
@ -378,6 +423,8 @@ static PyMethodDef dbm_methods[] = {
|
||||||
{"nextkey", (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__},
|
{"nextkey", (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__},
|
||||||
{"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__},
|
{"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__},
|
||||||
{"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__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 */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue