Index: Modules/dbmmodule.c =================================================================== --- Modules/dbmmodule.c (revision 71461) +++ Modules/dbmmodule.c (working copy) @@ -257,6 +257,30 @@ } static PyObject * +dbm__firstkey(register dbmobject *dp, PyObject *unused) +{ + datum key; + + check_dbmobject_open(dp); + key = dbm_firstkey(dp->di_dbm); + if (key.dptr) + return PyString_FromStringAndSize(key.dptr, key.dsize); + Py_RETURN_NONE; +} + +static PyObject * +dbm__nextkey(register dbmobject *dp, PyObject *unused) +{ + datum nextkey; + + check_dbmobject_open(dp); + nextkey = dbm_nextkey(dp->di_dbm); + if (nextkey.dptr) + return PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize); + Py_RETURN_NONE; +} + +static PyObject * dbm_get(register dbmobject *dp, PyObject *args) { datum key, val; @@ -320,6 +344,11 @@ "keys() -> list\nReturn a list of all keys in the database."}, {"has_key", (PyCFunction)dbm_has_key, METH_VARARGS, "has_key(key} -> boolean\nReturn true iff key is in the database."}, + {"firstkey", (PyCFunction)dbm__firstkey, METH_NOARGS, + "firstkey() -> key\nReturn the starting key."}, + {"nextkey", (PyCFunction)dbm__nextkey, METH_NOARGS, + "nextkey() -> next_key\n" + "Returns the key that follows key in the traversal."}, {"get", (PyCFunction)dbm_get, METH_VARARGS, "get(key[, default]) -> value\n" "Return the value for key if present, otherwise default."}, @@ -336,6 +365,25 @@ return Py_FindMethod(dbm_methods, (PyObject *)dp, name); } +static PyObject * +dbm_iternext(dbmobject *dp) +{ + datum key; + + check_dbmobject_open(dp); + key = dbm_nextkey(dp->di_dbm); + if (dbm_error(dp->di_dbm)) { + dbm_clearerr(dp->di_dbm); + PyErr_SetString(DbmError, ""); + return NULL; + } + if (key.dptr == NULL) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + return PyString_FromStringAndSize(key.dptr, key.dsize); +} + static PyTypeObject Dbmtype = { PyVarObject_HEAD_INIT(NULL, 0) "dbm.dbm", @@ -357,6 +405,13 @@ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_xxx4*/ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)dbm_iternext, /* tp_iternext */ }; /* ----------------------------------------------------------------- */ @@ -415,3 +470,4 @@ if (DbmError != NULL) PyDict_SetItemString(d, "error", DbmError); } + Index: Modules/gdbmmodule.c =================================================================== --- Modules/gdbmmodule.c (revision 71461) +++ Modules/gdbmmodule.c (working copy) @@ -403,6 +403,25 @@ return Py_FindMethod(dbm_methods, (PyObject *)dp, name); } +static PyObject * +dbm_iternext(dbmobject *dp) +{ + static datum key = {NULL, 0}; + + check_dbmobject_open(dp); + if (key.dptr == NULL) + key = gdbm_firstkey(dp->di_dbm); + else { + free(key.dptr); + key = gdbm_nextkey(dp->di_dbm, key); + } + if (key.dptr == NULL) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + return PyString_FromStringAndSize(key.dptr, key.dsize); +} + static PyTypeObject Dbmtype = { PyVarObject_HEAD_INIT(0, 0) "gdbm.gdbm", @@ -425,6 +444,12 @@ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_xxx4*/ gdbm_object__doc__, /*tp_doc*/ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)dbm_iternext, /* tp_iternext */ }; /* ----------------------------------------------------------------- */