--- /dev/null
+++ b/3.10/Modules/_dbmmodule.c
@@ -0,0 +1,559 @@
+
+/* DBM module using dictionary interface */
+
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* Some Linux systems install gdbm/ndbm.h, but not ndbm.h.  This supports
+ * whichever configure was able to locate.
+ */
+#if defined(HAVE_NDBM_H)
+#include <ndbm.h>
+static const char which_dbm[] = "GNU gdbm";  /* EMX port of GDBM */
+#elif defined(HAVE_GDBM_NDBM_H)
+#include <gdbm/ndbm.h>
+static const char which_dbm[] = "GNU gdbm";
+#elif defined(HAVE_GDBM_DASH_NDBM_H)
+#include <gdbm-ndbm.h>
+static const char which_dbm[] = "GNU gdbm";
+#elif defined(HAVE_BERKDB_H)
+#include <db.h>
+static const char which_dbm[] = "Berkeley DB";
+#else
+#error "No ndbm.h available!"
+#endif
+
+typedef struct {
+    PyTypeObject *dbm_type;
+    PyObject *dbm_error;
+} _dbm_state;
+
+static inline _dbm_state*
+get_dbm_state(PyObject *module)
+{
+    void *state = PyModule_GetState(module);
+    assert(state != NULL);
+    return (_dbm_state *)state;
+}
+
+/*[clinic input]
+module _dbm
+class _dbm.dbm "dbmobject *" "&Dbmtype"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b1aa8756d16150e]*/
+
+typedef struct {
+    PyObject_HEAD
+    int flags;
+    int di_size;        /* -1 means recompute */
+    DBM *di_dbm;
+} dbmobject;
+
+#include "clinic/_dbmmodule.c.h"
+
+#define check_dbmobject_open(v, err)                                \
+    if ((v)->di_dbm == NULL) {                                      \
+        PyErr_SetString(err, "DBM object has already been closed"); \
+        return NULL;                                                \
+    }
+
+static PyObject *
+newdbmobject(_dbm_state *state, const char *file, int flags, int mode)
+{
+    dbmobject *dp;
+
+    dp = PyObject_New(dbmobject, state->dbm_type);
+    if (dp == NULL)
+        return NULL;
+    dp->di_size = -1;
+    dp->flags = flags;
+    /* See issue #19296 */
+    if ( (dp->di_dbm = dbm_open((char *)file, flags, mode)) == 0 ) {
+        PyErr_SetFromErrnoWithFilename(state->dbm_error, file);
+        Py_DECREF(dp);
+        return NULL;
+    }
+    return (PyObject *)dp;
+}
+
+/* Methods */
+
+static void
+dbm_dealloc(dbmobject *dp)
+{
+    if (dp->di_dbm) {
+        dbm_close(dp->di_dbm);
+    }
+    PyTypeObject *tp = Py_TYPE(dp);
+    tp->tp_free(dp);
+    Py_DECREF(tp);
+}
+
+static Py_ssize_t
+dbm_length(dbmobject *dp)
+{
+    _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
+    assert(state != NULL);
+    if (dp->di_dbm == NULL) {
+             PyErr_SetString(state->dbm_error, "DBM object has already been closed");
+             return -1;
+    }
+    if ( dp->di_size < 0 ) {
+        datum key;
+        int size;
+
+        size = 0;
+        for ( key=dbm_firstkey(dp->di_dbm); key.dptr;
+              key = dbm_nextkey(dp->di_dbm))
+            size++;
+        dp->di_size = size;
+    }
+    return dp->di_size;
+}
+
+static PyObject *
+dbm_subscript(dbmobject *dp, PyObject *key)
+{
+    datum drec, krec;
+    Py_ssize_t tmp_size;
+    _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
+    assert(state != NULL);
+    if (!PyArg_Parse(key, "s#", &krec.dptr, &tmp_size)) {
+        return NULL;
+    }
+
+    krec.dsize = tmp_size;
+    check_dbmobject_open(dp, state->dbm_error);
+    drec = dbm_fetch(dp->di_dbm, krec);
+    if ( drec.dptr == 0 ) {
+        PyErr_SetObject(PyExc_KeyError, key);
+        return NULL;
+    }
+    if ( dbm_error(dp->di_dbm) ) {
+        dbm_clearerr(dp->di_dbm);
+        PyErr_SetString(state->dbm_error, "");
+        return NULL;
+    }
+    return PyBytes_FromStringAndSize(drec.dptr, drec.dsize);
+}
+
+static int
+dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
+{
+    datum krec, drec;
+    Py_ssize_t tmp_size;
+
+    if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) {
+        PyErr_SetString(PyExc_TypeError,
+                        "dbm mappings have bytes or string keys only");
+        return -1;
+    }
+    _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
+    assert(state != NULL);
+    krec.dsize = tmp_size;
+    if (dp->di_dbm == NULL) {
+             PyErr_SetString(state->dbm_error, "DBM object has already been closed");
+             return -1;
+    }
+    dp->di_size = -1;
+    if (w == NULL) {
+        if ( dbm_delete(dp->di_dbm, krec) < 0 ) {
+            dbm_clearerr(dp->di_dbm);
+            /* we might get a failure for reasons like file corrupted,
+               but we are not able to distinguish it */
+            if (dp->flags & O_RDWR) {
+                PyErr_SetObject(PyExc_KeyError, v);
+            }
+            else {
+                PyErr_SetString(state->dbm_error, "cannot delete item from database");
+            }
+            return -1;
+        }
+    } else {
+        if ( !PyArg_Parse(w, "s#", &drec.dptr, &tmp_size) ) {
+            PyErr_SetString(PyExc_TypeError,
+                 "dbm mappings have bytes or string elements only");
+            return -1;
+        }
+        drec.dsize = tmp_size;
+        if ( dbm_store(dp->di_dbm, krec, drec, DBM_REPLACE) < 0 ) {
+            dbm_clearerr(dp->di_dbm);
+            PyErr_SetString(state->dbm_error,
+                            "cannot add item to database");
+            return -1;
+        }
+    }
+    if ( dbm_error(dp->di_dbm) ) {
+        dbm_clearerr(dp->di_dbm);
+        PyErr_SetString(state->dbm_error, "");
+        return -1;
+    }
+    return 0;
+}
+
+/*[clinic input]
+_dbm.dbm.close
+
+Close the database.
+[clinic start generated code]*/
+
+static PyObject *
+_dbm_dbm_close_impl(dbmobject *self)
+/*[clinic end generated code: output=c8dc5b6709600b86 input=046db72377d51be8]*/
+{
+    if (self->di_dbm) {
+        dbm_close(self->di_dbm);
+    }
+    self->di_dbm = NULL;
+    Py_RETURN_NONE;
+}
+
+/*[clinic input]
+_dbm.dbm.keys
+
+    cls: defining_class
+
+Return a list of all keys in the database.
+[clinic start generated code]*/
+
+static PyObject *
+_dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=f2a593b3038e5996 input=d3706a28fc051097]*/
+{
+    PyObject *v, *item;
+    datum key;
+    int err;
+
+    _dbm_state *state = PyType_GetModuleState(cls);
+    assert(state != NULL);
+    check_dbmobject_open(self, state->dbm_error);
+    v = PyList_New(0);
+    if (v == NULL) {
+        return NULL;
+    }
+    for (key = dbm_firstkey(self->di_dbm); key.dptr;
+         key = dbm_nextkey(self->di_dbm)) {
+        item = PyBytes_FromStringAndSize(key.dptr, key.dsize);
+        if (item == NULL) {
+            Py_DECREF(v);
+            return NULL;
+        }
+        err = PyList_Append(v, item);
+        Py_DECREF(item);
+        if (err != 0) {
+            Py_DECREF(v);
+            return NULL;
+        }
+    }
+    return v;
+}
+
+static int
+dbm_contains(PyObject *self, PyObject *arg)
+{
+    dbmobject *dp = (dbmobject *)self;
+    datum key, val;
+    Py_ssize_t size;
+
+    _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
+    assert(state != NULL);
+    if ((dp)->di_dbm == NULL) {
+        PyErr_SetString(state->dbm_error,
+                        "DBM object has already been closed");
+         return -1;
+    }
+    if (PyUnicode_Check(arg)) {
+        key.dptr = (char *)PyUnicode_AsUTF8AndSize(arg, &size);
+        key.dsize = size;
+        if (key.dptr == NULL)
+            return -1;
+    }
+    else if (!PyBytes_Check(arg)) {
+        PyErr_Format(PyExc_TypeError,
+                     "dbm key must be bytes or string, not %.100s",
+                     Py_TYPE(arg)->tp_name);
+        return -1;
+    }
+    else {
+        key.dptr = PyBytes_AS_STRING(arg);
+        key.dsize = PyBytes_GET_SIZE(arg);
+    }
+    val = dbm_fetch(dp->di_dbm, key);
+    return val.dptr != NULL;
+}
+
+/*[clinic input]
+_dbm.dbm.get
+    cls: defining_class
+    key: str(accept={str, robuffer}, zeroes=True)
+    default: object = None
+    /
+
+Return the value for key if present, otherwise default.
+[clinic start generated code]*/
+
+static PyObject *
+_dbm_dbm_get_impl(dbmobject *self, PyTypeObject *cls, const char *key,
+                  Py_ssize_clean_t key_length, PyObject *default_value)
+/*[clinic end generated code: output=34851b5dc1c664dc input=66b993b8349fa8c1]*/
+{
+    datum dbm_key, val;
+    _dbm_state *state = PyType_GetModuleState(cls);
+    assert(state != NULL);
+    dbm_key.dptr = (char *)key;
+    dbm_key.dsize = key_length;
+    check_dbmobject_open(self, state->dbm_error);
+    val = dbm_fetch(self->di_dbm, dbm_key);
+    if (val.dptr != NULL) {
+        return PyBytes_FromStringAndSize(val.dptr, val.dsize);
+    }
+
+    Py_INCREF(default_value);
+    return default_value;
+}
+
+/*[clinic input]
+_dbm.dbm.setdefault
+    cls: defining_class
+    key: str(accept={str, robuffer}, zeroes=True)
+    default: object(c_default="NULL") = b''
+    /
+
+Return the value for key if present, otherwise default.
+
+If key is not in the database, it is inserted with default as the value.
+[clinic start generated code]*/
+
+static PyObject *
+_dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key,
+                         Py_ssize_clean_t key_length,
+                         PyObject *default_value)
+/*[clinic end generated code: output=d5c68fe673886767 input=126a3ff15c5f8232]*/
+{
+    datum dbm_key, val;
+    Py_ssize_t tmp_size;
+    _dbm_state *state = PyType_GetModuleState(cls);
+    assert(state != NULL);
+    dbm_key.dptr = (char *)key;
+    dbm_key.dsize = key_length;
+    check_dbmobject_open(self, state->dbm_error);
+    val = dbm_fetch(self->di_dbm, dbm_key);
+    if (val.dptr != NULL) {
+        return PyBytes_FromStringAndSize(val.dptr, val.dsize);
+    }
+    if (default_value == NULL) {
+        default_value = PyBytes_FromStringAndSize(NULL, 0);
+        if (default_value == NULL) {
+            return NULL;
+        }
+        val.dptr = NULL;
+        val.dsize = 0;
+    }
+    else {
+        if ( !PyArg_Parse(default_value, "s#", &val.dptr, &tmp_size) ) {
+            PyErr_SetString(PyExc_TypeError,
+                "dbm mappings have bytes or string elements only");
+            return NULL;
+        }
+        val.dsize = tmp_size;
+        Py_INCREF(default_value);
+    }
+    if (dbm_store(self->di_dbm, dbm_key, val, DBM_INSERT) < 0) {
+        dbm_clearerr(self->di_dbm);
+        PyErr_SetString(state->dbm_error, "cannot add item to database");
+        Py_DECREF(default_value);
+        return NULL;
+    }
+    return default_value;
+}
+
+static PyObject *
+dbm__enter__(PyObject *self, PyObject *args)
+{
+    Py_INCREF(self);
+    return self;
+}
+
+static PyObject *
+dbm__exit__(PyObject *self, PyObject *args)
+{
+    _Py_IDENTIFIER(close);
+    return _PyObject_CallMethodIdNoArgs(self, &PyId_close);
+}
+
+static PyMethodDef dbm_methods[] = {
+    _DBM_DBM_CLOSE_METHODDEF
+    _DBM_DBM_KEYS_METHODDEF
+    _DBM_DBM_GET_METHODDEF
+    _DBM_DBM_SETDEFAULT_METHODDEF
+    {"__enter__", dbm__enter__, METH_NOARGS, NULL},
+    {"__exit__",  dbm__exit__, METH_VARARGS, NULL},
+    {NULL,  NULL}           /* sentinel */
+};
+
+static PyType_Slot dbmtype_spec_slots[] = {
+    {Py_tp_dealloc, dbm_dealloc},
+    {Py_tp_methods, dbm_methods},
+    {Py_sq_contains, dbm_contains},
+    {Py_mp_length, dbm_length},
+    {Py_mp_subscript, dbm_subscript},
+    {Py_mp_ass_subscript, dbm_ass_sub},
+    {0, 0}
+};
+
+
+static PyType_Spec dbmtype_spec = {
+    .name = "_dbm.dbm",
+    .basicsize = sizeof(dbmobject),
+    // Calling PyType_GetModuleState() on a subclass is not safe.
+    // dbmtype_spec does not have Py_TPFLAGS_BASETYPE flag
+    // which prevents to create a subclass.
+    // So calling PyType_GetModuleState() in this file is always safe.
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
+    .slots = dbmtype_spec_slots,
+};
+
+/* ----------------------------------------------------------------- */
+
+/*[clinic input]
+
+_dbm.open as dbmopen
+
+    filename: unicode
+        The filename to open.
+
+    flags: str="r"
+        How to open the file.  "r" for reading, "w" for writing, etc.
+
+    mode: int(py_default="0o666") = 0o666
+        If creating a new file, the mode bits for the new file
+        (e.g. os.O_RDWR).
+
+    /
+
+Return a database object.
+
+[clinic start generated code]*/
+
+static PyObject *
+dbmopen_impl(PyObject *module, PyObject *filename, const char *flags,
+             int mode)
+/*[clinic end generated code: output=9527750f5df90764 input=376a9d903a50df59]*/
+{
+    int iflags;
+    _dbm_state *state =  get_dbm_state(module);
+    assert(state != NULL);
+    if (strcmp(flags, "r") == 0) {
+        iflags = O_RDONLY;
+    }
+    else if (strcmp(flags, "w") == 0) {
+        iflags = O_RDWR;
+    }
+    else if (strcmp(flags, "rw") == 0) {
+        /* Backward compatibility */
+        iflags = O_RDWR|O_CREAT;
+    }
+    else if (strcmp(flags, "c") == 0) {
+        iflags = O_RDWR|O_CREAT;
+    }
+    else if (strcmp(flags, "n") == 0) {
+        iflags = O_RDWR|O_CREAT|O_TRUNC;
+    }
+    else {
+        PyErr_SetString(state->dbm_error,
+                        "arg 2 to open should be 'r', 'w', 'c', or 'n'");
+        return NULL;
+    }
+
+    PyObject *filenamebytes = PyUnicode_EncodeFSDefault(filename);
+    if (filenamebytes == NULL) {
+        return NULL;
+    }
+    const char *name = PyBytes_AS_STRING(filenamebytes);
+    if (strlen(name) != (size_t)PyBytes_GET_SIZE(filenamebytes)) {
+        Py_DECREF(filenamebytes);
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        return NULL;
+    }
+    PyObject *self = newdbmobject(state, name, iflags, mode);
+    Py_DECREF(filenamebytes);
+    return self;
+}
+
+static PyMethodDef dbmmodule_methods[] = {
+    DBMOPEN_METHODDEF
+    { 0, 0 },
+};
+
+static int
+_dbm_exec(PyObject *module)
+{
+    _dbm_state *state = get_dbm_state(module);
+    state->dbm_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
+                                                        &dbmtype_spec, NULL);
+    if (state->dbm_type == NULL) {
+        return -1;
+    }
+    state->dbm_error = PyErr_NewException("_dbm.error", PyExc_OSError, NULL);
+    if (state->dbm_error == NULL) {
+        return -1;
+    }
+    if (PyModule_AddStringConstant(module, "library", which_dbm) < 0) {
+        return -1;
+    }
+    if (PyModule_AddType(module, (PyTypeObject *)state->dbm_error) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static int
+_dbm_module_traverse(PyObject *module, visitproc visit, void *arg)
+{
+    _dbm_state *state = get_dbm_state(module);
+    Py_VISIT(state->dbm_error);
+    Py_VISIT(state->dbm_type);
+    return 0;
+}
+
+static int
+_dbm_module_clear(PyObject *module)
+{
+    _dbm_state *state = get_dbm_state(module);
+    Py_CLEAR(state->dbm_error);
+    Py_CLEAR(state->dbm_type);
+    return 0;
+}
+
+static void
+_dbm_module_free(void *module)
+{
+    _dbm_module_clear((PyObject *)module);
+}
+
+static PyModuleDef_Slot _dbmmodule_slots[] = {
+    {Py_mod_exec, _dbm_exec},
+    {0, NULL}
+};
+
+static struct PyModuleDef _dbmmodule = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "_dbm",
+    .m_size = sizeof(_dbm_state),
+    .m_methods = dbmmodule_methods,
+    .m_slots = _dbmmodule_slots,
+    .m_traverse = _dbm_module_traverse,
+    .m_clear = _dbm_module_clear,
+    .m_free = _dbm_module_free,
+};
+
+PyMODINIT_FUNC
+PyInit__dbm(void)
+{
+    return PyModuleDef_Init(&_dbmmodule);
+}
--- /dev/null
+++ b/3.10/Modules/clinic/_dbmmodule.c.h
@@ -0,0 +1,190 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_dbm_dbm_close__doc__,
+"close($self, /)\n"
+"--\n"
+"\n"
+"Close the database.");
+
+#define _DBM_DBM_CLOSE_METHODDEF    \
+    {"close", (PyCFunction)_dbm_dbm_close, METH_NOARGS, _dbm_dbm_close__doc__},
+
+static PyObject *
+_dbm_dbm_close_impl(dbmobject *self);
+
+static PyObject *
+_dbm_dbm_close(dbmobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _dbm_dbm_close_impl(self);
+}
+
+PyDoc_STRVAR(_dbm_dbm_keys__doc__,
+"keys($self, /)\n"
+"--\n"
+"\n"
+"Return a list of all keys in the database.");
+
+#define _DBM_DBM_KEYS_METHODDEF    \
+    {"keys", (PyCFunction)(void(*)(void))_dbm_dbm_keys, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_keys__doc__},
+
+static PyObject *
+_dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls);
+
+static PyObject *
+_dbm_dbm_keys(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = { NULL};
+    static _PyArg_Parser _parser = {":keys", _keywords, 0};
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser
+        )) {
+        goto exit;
+    }
+    return_value = _dbm_dbm_keys_impl(self, cls);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_dbm_dbm_get__doc__,
+"get($self, key, default=None, /)\n"
+"--\n"
+"\n"
+"Return the value for key if present, otherwise default.");
+
+#define _DBM_DBM_GET_METHODDEF    \
+    {"get", (PyCFunction)(void(*)(void))_dbm_dbm_get, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_get__doc__},
+
+static PyObject *
+_dbm_dbm_get_impl(dbmobject *self, PyTypeObject *cls, const char *key,
+                  Py_ssize_clean_t key_length, PyObject *default_value);
+
+static PyObject *
+_dbm_dbm_get(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {"s#|O:get", _keywords, 0};
+    const char *key;
+    Py_ssize_clean_t key_length;
+    PyObject *default_value = Py_None;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &key, &key_length, &default_value)) {
+        goto exit;
+    }
+    return_value = _dbm_dbm_get_impl(self, cls, key, key_length, default_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_dbm_dbm_setdefault__doc__,
+"setdefault($self, key, default=b\'\', /)\n"
+"--\n"
+"\n"
+"Return the value for key if present, otherwise default.\n"
+"\n"
+"If key is not in the database, it is inserted with default as the value.");
+
+#define _DBM_DBM_SETDEFAULT_METHODDEF    \
+    {"setdefault", (PyCFunction)(void(*)(void))_dbm_dbm_setdefault, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_setdefault__doc__},
+
+static PyObject *
+_dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key,
+                         Py_ssize_clean_t key_length,
+                         PyObject *default_value);
+
+static PyObject *
+_dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {"s#|O:setdefault", _keywords, 0};
+    const char *key;
+    Py_ssize_clean_t key_length;
+    PyObject *default_value = NULL;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &key, &key_length, &default_value)) {
+        goto exit;
+    }
+    return_value = _dbm_dbm_setdefault_impl(self, cls, key, key_length, default_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(dbmopen__doc__,
+"open($module, filename, flags=\'r\', mode=0o666, /)\n"
+"--\n"
+"\n"
+"Return a database object.\n"
+"\n"
+"  filename\n"
+"    The filename to open.\n"
+"  flags\n"
+"    How to open the file.  \"r\" for reading, \"w\" for writing, etc.\n"
+"  mode\n"
+"    If creating a new file, the mode bits for the new file\n"
+"    (e.g. os.O_RDWR).");
+
+#define DBMOPEN_METHODDEF    \
+    {"open", (PyCFunction)(void(*)(void))dbmopen, METH_FASTCALL, dbmopen__doc__},
+
+static PyObject *
+dbmopen_impl(PyObject *module, PyObject *filename, const char *flags,
+             int mode);
+
+static PyObject *
+dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *filename;
+    const char *flags = "r";
+    int mode = 438;
+
+    if (!_PyArg_CheckPositional("open", nargs, 1, 3)) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(args[0])) {
+        _PyArg_BadArgument("open", "argument 1", "str", args[0]);
+        goto exit;
+    }
+    if (PyUnicode_READY(args[0]) == -1) {
+        goto exit;
+    }
+    filename = args[0];
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    if (!PyUnicode_Check(args[1])) {
+        _PyArg_BadArgument("open", "argument 2", "str", args[1]);
+        goto exit;
+    }
+    Py_ssize_t flags_length;
+    flags = PyUnicode_AsUTF8AndSize(args[1], &flags_length);
+    if (flags == NULL) {
+        goto exit;
+    }
+    if (strlen(flags) != (size_t)flags_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    mode = _PyLong_AsInt(args[2]);
+    if (mode == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = dbmopen_impl(module, filename, flags, mode);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: output=6947b1115df66f7c input=a9049054013a1b77]*/
--- a/3.10/setup.py
+++ b/3.10/setup.py
@@ -548,6 +548,69 @@ class PyBuildExt(build_ext):
 
         # XXX Omitted modules: gl, pure, dl, SGI-specific modules
 
+        # The standard Unix dbm module:
+        if True:
+            dbm_order = "gdbm:ndbm:bdb".split(":")
+            dbmext = None
+            for cand in dbm_order:
+                if cand == "ndbm":
+                    if find_file("ndbm.h", inc_dirs, []) is not None:
+                        # Some systems have -lndbm, others have -lgdbm_compat,
+                        # others don't have either
+                        if self.compiler.find_library_file(lib_dirs,
+                                                               'ndbm'):
+                            ndbm_libs = ['ndbm']
+                        elif self.compiler.find_library_file(lib_dirs,
+                                                             'gdbm_compat'):
+                            ndbm_libs = ['gdbm_compat']
+                        else:
+                            ndbm_libs = []
+                        dbmext = Extension('_dbm', ['Modules/_dbmmodule.c'],
+                                           define_macros=[
+                                               ('HAVE_NDBM_H',None),
+                                               ],
+                                           libraries=ndbm_libs)
+                        break
+
+                elif cand == "gdbm":
+                    if self.compiler.find_library_file(lib_dirs, 'gdbm'):
+                        gdbm_libs = ['gdbm']
+                        if self.compiler.find_library_file(lib_dirs,
+                                                               'gdbm_compat'):
+                            gdbm_libs.append('gdbm_compat')
+                        if find_file("gdbm/ndbm.h", inc_dirs, []) is not None:
+                            dbmext = Extension(
+                                '_dbm', ['Modules/_dbmmodule.c'],
+                                define_macros=[
+                                    ('HAVE_GDBM_NDBM_H', None),
+                                    ],
+                                libraries = gdbm_libs)
+                            break
+                        if find_file("gdbm-ndbm.h", inc_dirs, []) is not None:
+                            dbmext = Extension(
+                                '_dbm', ['Modules/_dbmmodule.c'],
+                                define_macros=[
+                                    ('HAVE_GDBM_DASH_NDBM_H', None),
+                                    ],
+                                libraries = gdbm_libs)
+                            break
+                elif cand == "bdb":
+                    if db_incs is not None:
+                        dbmext = Extension('_dbm', ['Modules/_dbmmodule.c'],
+                                           library_dirs=dblib_dir,
+                                           runtime_library_dirs=dblib_dir,
+                                           include_dirs=db_incs,
+                                           define_macros=[
+                                               ('HAVE_BERKDB_H', None),
+                                               ('DB_DBM_HSEARCH', None),
+                                               ],
+                                           libraries=dblibs)
+                        break
+            if dbmext is not None:
+                exts.append(dbmext)
+            else:
+                missing.append('_dbm')
+
         # Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
         if (True or 'gdbm' in dbm_order and
             self.compiler.find_library_file(lib_dirs, 'gdbm')):
--- /dev/null
+++ b/3.11/Modules/_dbmmodule.c
@@ -0,0 +1,559 @@
+
+/* DBM module using dictionary interface */
+
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* Some Linux systems install gdbm/ndbm.h, but not ndbm.h.  This supports
+ * whichever configure was able to locate.
+ */
+#if defined(HAVE_NDBM_H)
+#include <ndbm.h>
+static const char which_dbm[] = "GNU gdbm";  /* EMX port of GDBM */
+#elif defined(HAVE_GDBM_NDBM_H)
+#include <gdbm/ndbm.h>
+static const char which_dbm[] = "GNU gdbm";
+#elif defined(HAVE_GDBM_DASH_NDBM_H)
+#include <gdbm-ndbm.h>
+static const char which_dbm[] = "GNU gdbm";
+#elif defined(HAVE_BERKDB_H)
+#include <db.h>
+static const char which_dbm[] = "Berkeley DB";
+#else
+#error "No ndbm.h available!"
+#endif
+
+typedef struct {
+    PyTypeObject *dbm_type;
+    PyObject *dbm_error;
+} _dbm_state;
+
+static inline _dbm_state*
+get_dbm_state(PyObject *module)
+{
+    void *state = PyModule_GetState(module);
+    assert(state != NULL);
+    return (_dbm_state *)state;
+}
+
+/*[clinic input]
+module _dbm
+class _dbm.dbm "dbmobject *" "&Dbmtype"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b1aa8756d16150e]*/
+
+typedef struct {
+    PyObject_HEAD
+    int flags;
+    int di_size;        /* -1 means recompute */
+    DBM *di_dbm;
+} dbmobject;
+
+#include "clinic/_dbmmodule.c.h"
+
+#define check_dbmobject_open(v, err)                                \
+    if ((v)->di_dbm == NULL) {                                      \
+        PyErr_SetString(err, "DBM object has already been closed"); \
+        return NULL;                                                \
+    }
+
+static PyObject *
+newdbmobject(_dbm_state *state, const char *file, int flags, int mode)
+{
+    dbmobject *dp;
+
+    dp = PyObject_New(dbmobject, state->dbm_type);
+    if (dp == NULL)
+        return NULL;
+    dp->di_size = -1;
+    dp->flags = flags;
+    /* See issue #19296 */
+    if ( (dp->di_dbm = dbm_open((char *)file, flags, mode)) == 0 ) {
+        PyErr_SetFromErrnoWithFilename(state->dbm_error, file);
+        Py_DECREF(dp);
+        return NULL;
+    }
+    return (PyObject *)dp;
+}
+
+/* Methods */
+
+static void
+dbm_dealloc(dbmobject *dp)
+{
+    if (dp->di_dbm) {
+        dbm_close(dp->di_dbm);
+    }
+    PyTypeObject *tp = Py_TYPE(dp);
+    tp->tp_free(dp);
+    Py_DECREF(tp);
+}
+
+static Py_ssize_t
+dbm_length(dbmobject *dp)
+{
+    _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
+    assert(state != NULL);
+    if (dp->di_dbm == NULL) {
+             PyErr_SetString(state->dbm_error, "DBM object has already been closed");
+             return -1;
+    }
+    if ( dp->di_size < 0 ) {
+        datum key;
+        int size;
+
+        size = 0;
+        for ( key=dbm_firstkey(dp->di_dbm); key.dptr;
+              key = dbm_nextkey(dp->di_dbm))
+            size++;
+        dp->di_size = size;
+    }
+    return dp->di_size;
+}
+
+static PyObject *
+dbm_subscript(dbmobject *dp, PyObject *key)
+{
+    datum drec, krec;
+    Py_ssize_t tmp_size;
+    _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
+    assert(state != NULL);
+    if (!PyArg_Parse(key, "s#", &krec.dptr, &tmp_size)) {
+        return NULL;
+    }
+
+    krec.dsize = tmp_size;
+    check_dbmobject_open(dp, state->dbm_error);
+    drec = dbm_fetch(dp->di_dbm, krec);
+    if ( drec.dptr == 0 ) {
+        PyErr_SetObject(PyExc_KeyError, key);
+        return NULL;
+    }
+    if ( dbm_error(dp->di_dbm) ) {
+        dbm_clearerr(dp->di_dbm);
+        PyErr_SetString(state->dbm_error, "");
+        return NULL;
+    }
+    return PyBytes_FromStringAndSize(drec.dptr, drec.dsize);
+}
+
+static int
+dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
+{
+    datum krec, drec;
+    Py_ssize_t tmp_size;
+
+    if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) {
+        PyErr_SetString(PyExc_TypeError,
+                        "dbm mappings have bytes or string keys only");
+        return -1;
+    }
+    _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
+    assert(state != NULL);
+    krec.dsize = tmp_size;
+    if (dp->di_dbm == NULL) {
+             PyErr_SetString(state->dbm_error, "DBM object has already been closed");
+             return -1;
+    }
+    dp->di_size = -1;
+    if (w == NULL) {
+        if ( dbm_delete(dp->di_dbm, krec) < 0 ) {
+            dbm_clearerr(dp->di_dbm);
+            /* we might get a failure for reasons like file corrupted,
+               but we are not able to distinguish it */
+            if (dp->flags & O_RDWR) {
+                PyErr_SetObject(PyExc_KeyError, v);
+            }
+            else {
+                PyErr_SetString(state->dbm_error, "cannot delete item from database");
+            }
+            return -1;
+        }
+    } else {
+        if ( !PyArg_Parse(w, "s#", &drec.dptr, &tmp_size) ) {
+            PyErr_SetString(PyExc_TypeError,
+                 "dbm mappings have bytes or string elements only");
+            return -1;
+        }
+        drec.dsize = tmp_size;
+        if ( dbm_store(dp->di_dbm, krec, drec, DBM_REPLACE) < 0 ) {
+            dbm_clearerr(dp->di_dbm);
+            PyErr_SetString(state->dbm_error,
+                            "cannot add item to database");
+            return -1;
+        }
+    }
+    if ( dbm_error(dp->di_dbm) ) {
+        dbm_clearerr(dp->di_dbm);
+        PyErr_SetString(state->dbm_error, "");
+        return -1;
+    }
+    return 0;
+}
+
+/*[clinic input]
+_dbm.dbm.close
+
+Close the database.
+[clinic start generated code]*/
+
+static PyObject *
+_dbm_dbm_close_impl(dbmobject *self)
+/*[clinic end generated code: output=c8dc5b6709600b86 input=046db72377d51be8]*/
+{
+    if (self->di_dbm) {
+        dbm_close(self->di_dbm);
+    }
+    self->di_dbm = NULL;
+    Py_RETURN_NONE;
+}
+
+/*[clinic input]
+_dbm.dbm.keys
+
+    cls: defining_class
+
+Return a list of all keys in the database.
+[clinic start generated code]*/
+
+static PyObject *
+_dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=f2a593b3038e5996 input=d3706a28fc051097]*/
+{
+    PyObject *v, *item;
+    datum key;
+    int err;
+
+    _dbm_state *state = PyType_GetModuleState(cls);
+    assert(state != NULL);
+    check_dbmobject_open(self, state->dbm_error);
+    v = PyList_New(0);
+    if (v == NULL) {
+        return NULL;
+    }
+    for (key = dbm_firstkey(self->di_dbm); key.dptr;
+         key = dbm_nextkey(self->di_dbm)) {
+        item = PyBytes_FromStringAndSize(key.dptr, key.dsize);
+        if (item == NULL) {
+            Py_DECREF(v);
+            return NULL;
+        }
+        err = PyList_Append(v, item);
+        Py_DECREF(item);
+        if (err != 0) {
+            Py_DECREF(v);
+            return NULL;
+        }
+    }
+    return v;
+}
+
+static int
+dbm_contains(PyObject *self, PyObject *arg)
+{
+    dbmobject *dp = (dbmobject *)self;
+    datum key, val;
+    Py_ssize_t size;
+
+    _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
+    assert(state != NULL);
+    if ((dp)->di_dbm == NULL) {
+        PyErr_SetString(state->dbm_error,
+                        "DBM object has already been closed");
+         return -1;
+    }
+    if (PyUnicode_Check(arg)) {
+        key.dptr = (char *)PyUnicode_AsUTF8AndSize(arg, &size);
+        key.dsize = size;
+        if (key.dptr == NULL)
+            return -1;
+    }
+    else if (!PyBytes_Check(arg)) {
+        PyErr_Format(PyExc_TypeError,
+                     "dbm key must be bytes or string, not %.100s",
+                     Py_TYPE(arg)->tp_name);
+        return -1;
+    }
+    else {
+        key.dptr = PyBytes_AS_STRING(arg);
+        key.dsize = PyBytes_GET_SIZE(arg);
+    }
+    val = dbm_fetch(dp->di_dbm, key);
+    return val.dptr != NULL;
+}
+
+/*[clinic input]
+_dbm.dbm.get
+    cls: defining_class
+    key: str(accept={str, robuffer}, zeroes=True)
+    default: object = None
+    /
+
+Return the value for key if present, otherwise default.
+[clinic start generated code]*/
+
+static PyObject *
+_dbm_dbm_get_impl(dbmobject *self, PyTypeObject *cls, const char *key,
+                  Py_ssize_clean_t key_length, PyObject *default_value)
+/*[clinic end generated code: output=34851b5dc1c664dc input=66b993b8349fa8c1]*/
+{
+    datum dbm_key, val;
+    _dbm_state *state = PyType_GetModuleState(cls);
+    assert(state != NULL);
+    dbm_key.dptr = (char *)key;
+    dbm_key.dsize = key_length;
+    check_dbmobject_open(self, state->dbm_error);
+    val = dbm_fetch(self->di_dbm, dbm_key);
+    if (val.dptr != NULL) {
+        return PyBytes_FromStringAndSize(val.dptr, val.dsize);
+    }
+
+    Py_INCREF(default_value);
+    return default_value;
+}
+
+/*[clinic input]
+_dbm.dbm.setdefault
+    cls: defining_class
+    key: str(accept={str, robuffer}, zeroes=True)
+    default: object(c_default="NULL") = b''
+    /
+
+Return the value for key if present, otherwise default.
+
+If key is not in the database, it is inserted with default as the value.
+[clinic start generated code]*/
+
+static PyObject *
+_dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key,
+                         Py_ssize_clean_t key_length,
+                         PyObject *default_value)
+/*[clinic end generated code: output=d5c68fe673886767 input=126a3ff15c5f8232]*/
+{
+    datum dbm_key, val;
+    Py_ssize_t tmp_size;
+    _dbm_state *state = PyType_GetModuleState(cls);
+    assert(state != NULL);
+    dbm_key.dptr = (char *)key;
+    dbm_key.dsize = key_length;
+    check_dbmobject_open(self, state->dbm_error);
+    val = dbm_fetch(self->di_dbm, dbm_key);
+    if (val.dptr != NULL) {
+        return PyBytes_FromStringAndSize(val.dptr, val.dsize);
+    }
+    if (default_value == NULL) {
+        default_value = PyBytes_FromStringAndSize(NULL, 0);
+        if (default_value == NULL) {
+            return NULL;
+        }
+        val.dptr = NULL;
+        val.dsize = 0;
+    }
+    else {
+        if ( !PyArg_Parse(default_value, "s#", &val.dptr, &tmp_size) ) {
+            PyErr_SetString(PyExc_TypeError,
+                "dbm mappings have bytes or string elements only");
+            return NULL;
+        }
+        val.dsize = tmp_size;
+        Py_INCREF(default_value);
+    }
+    if (dbm_store(self->di_dbm, dbm_key, val, DBM_INSERT) < 0) {
+        dbm_clearerr(self->di_dbm);
+        PyErr_SetString(state->dbm_error, "cannot add item to database");
+        Py_DECREF(default_value);
+        return NULL;
+    }
+    return default_value;
+}
+
+static PyObject *
+dbm__enter__(PyObject *self, PyObject *args)
+{
+    Py_INCREF(self);
+    return self;
+}
+
+static PyObject *
+dbm__exit__(PyObject *self, PyObject *args)
+{
+    _Py_IDENTIFIER(close);
+    return _PyObject_CallMethodIdNoArgs(self, &PyId_close);
+}
+
+static PyMethodDef dbm_methods[] = {
+    _DBM_DBM_CLOSE_METHODDEF
+    _DBM_DBM_KEYS_METHODDEF
+    _DBM_DBM_GET_METHODDEF
+    _DBM_DBM_SETDEFAULT_METHODDEF
+    {"__enter__", dbm__enter__, METH_NOARGS, NULL},
+    {"__exit__",  dbm__exit__, METH_VARARGS, NULL},
+    {NULL,  NULL}           /* sentinel */
+};
+
+static PyType_Slot dbmtype_spec_slots[] = {
+    {Py_tp_dealloc, dbm_dealloc},
+    {Py_tp_methods, dbm_methods},
+    {Py_sq_contains, dbm_contains},
+    {Py_mp_length, dbm_length},
+    {Py_mp_subscript, dbm_subscript},
+    {Py_mp_ass_subscript, dbm_ass_sub},
+    {0, 0}
+};
+
+
+static PyType_Spec dbmtype_spec = {
+    .name = "_dbm.dbm",
+    .basicsize = sizeof(dbmobject),
+    // Calling PyType_GetModuleState() on a subclass is not safe.
+    // dbmtype_spec does not have Py_TPFLAGS_BASETYPE flag
+    // which prevents to create a subclass.
+    // So calling PyType_GetModuleState() in this file is always safe.
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
+    .slots = dbmtype_spec_slots,
+};
+
+/* ----------------------------------------------------------------- */
+
+/*[clinic input]
+
+_dbm.open as dbmopen
+
+    filename: unicode
+        The filename to open.
+
+    flags: str="r"
+        How to open the file.  "r" for reading, "w" for writing, etc.
+
+    mode: int(py_default="0o666") = 0o666
+        If creating a new file, the mode bits for the new file
+        (e.g. os.O_RDWR).
+
+    /
+
+Return a database object.
+
+[clinic start generated code]*/
+
+static PyObject *
+dbmopen_impl(PyObject *module, PyObject *filename, const char *flags,
+             int mode)
+/*[clinic end generated code: output=9527750f5df90764 input=376a9d903a50df59]*/
+{
+    int iflags;
+    _dbm_state *state =  get_dbm_state(module);
+    assert(state != NULL);
+    if (strcmp(flags, "r") == 0) {
+        iflags = O_RDONLY;
+    }
+    else if (strcmp(flags, "w") == 0) {
+        iflags = O_RDWR;
+    }
+    else if (strcmp(flags, "rw") == 0) {
+        /* Backward compatibility */
+        iflags = O_RDWR|O_CREAT;
+    }
+    else if (strcmp(flags, "c") == 0) {
+        iflags = O_RDWR|O_CREAT;
+    }
+    else if (strcmp(flags, "n") == 0) {
+        iflags = O_RDWR|O_CREAT|O_TRUNC;
+    }
+    else {
+        PyErr_SetString(state->dbm_error,
+                        "arg 2 to open should be 'r', 'w', 'c', or 'n'");
+        return NULL;
+    }
+
+    PyObject *filenamebytes = PyUnicode_EncodeFSDefault(filename);
+    if (filenamebytes == NULL) {
+        return NULL;
+    }
+    const char *name = PyBytes_AS_STRING(filenamebytes);
+    if (strlen(name) != (size_t)PyBytes_GET_SIZE(filenamebytes)) {
+        Py_DECREF(filenamebytes);
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        return NULL;
+    }
+    PyObject *self = newdbmobject(state, name, iflags, mode);
+    Py_DECREF(filenamebytes);
+    return self;
+}
+
+static PyMethodDef dbmmodule_methods[] = {
+    DBMOPEN_METHODDEF
+    { 0, 0 },
+};
+
+static int
+_dbm_exec(PyObject *module)
+{
+    _dbm_state *state = get_dbm_state(module);
+    state->dbm_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
+                                                        &dbmtype_spec, NULL);
+    if (state->dbm_type == NULL) {
+        return -1;
+    }
+    state->dbm_error = PyErr_NewException("_dbm.error", PyExc_OSError, NULL);
+    if (state->dbm_error == NULL) {
+        return -1;
+    }
+    if (PyModule_AddStringConstant(module, "library", which_dbm) < 0) {
+        return -1;
+    }
+    if (PyModule_AddType(module, (PyTypeObject *)state->dbm_error) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static int
+_dbm_module_traverse(PyObject *module, visitproc visit, void *arg)
+{
+    _dbm_state *state = get_dbm_state(module);
+    Py_VISIT(state->dbm_error);
+    Py_VISIT(state->dbm_type);
+    return 0;
+}
+
+static int
+_dbm_module_clear(PyObject *module)
+{
+    _dbm_state *state = get_dbm_state(module);
+    Py_CLEAR(state->dbm_error);
+    Py_CLEAR(state->dbm_type);
+    return 0;
+}
+
+static void
+_dbm_module_free(void *module)
+{
+    _dbm_module_clear((PyObject *)module);
+}
+
+static PyModuleDef_Slot _dbmmodule_slots[] = {
+    {Py_mod_exec, _dbm_exec},
+    {0, NULL}
+};
+
+static struct PyModuleDef _dbmmodule = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "_dbm",
+    .m_size = sizeof(_dbm_state),
+    .m_methods = dbmmodule_methods,
+    .m_slots = _dbmmodule_slots,
+    .m_traverse = _dbm_module_traverse,
+    .m_clear = _dbm_module_clear,
+    .m_free = _dbm_module_free,
+};
+
+PyMODINIT_FUNC
+PyInit__dbm(void)
+{
+    return PyModuleDef_Init(&_dbmmodule);
+}
--- /dev/null
+++ b/3.11/Modules/clinic/_dbmmodule.c.h
@@ -0,0 +1,190 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(_dbm_dbm_close__doc__,
+"close($self, /)\n"
+"--\n"
+"\n"
+"Close the database.");
+
+#define _DBM_DBM_CLOSE_METHODDEF    \
+    {"close", (PyCFunction)_dbm_dbm_close, METH_NOARGS, _dbm_dbm_close__doc__},
+
+static PyObject *
+_dbm_dbm_close_impl(dbmobject *self);
+
+static PyObject *
+_dbm_dbm_close(dbmobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _dbm_dbm_close_impl(self);
+}
+
+PyDoc_STRVAR(_dbm_dbm_keys__doc__,
+"keys($self, /)\n"
+"--\n"
+"\n"
+"Return a list of all keys in the database.");
+
+#define _DBM_DBM_KEYS_METHODDEF    \
+    {"keys", (PyCFunction)(void(*)(void))_dbm_dbm_keys, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_keys__doc__},
+
+static PyObject *
+_dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls);
+
+static PyObject *
+_dbm_dbm_keys(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = { NULL};
+    static _PyArg_Parser _parser = {":keys", _keywords, 0};
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser
+        )) {
+        goto exit;
+    }
+    return_value = _dbm_dbm_keys_impl(self, cls);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_dbm_dbm_get__doc__,
+"get($self, key, default=None, /)\n"
+"--\n"
+"\n"
+"Return the value for key if present, otherwise default.");
+
+#define _DBM_DBM_GET_METHODDEF    \
+    {"get", (PyCFunction)(void(*)(void))_dbm_dbm_get, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_get__doc__},
+
+static PyObject *
+_dbm_dbm_get_impl(dbmobject *self, PyTypeObject *cls, const char *key,
+                  Py_ssize_clean_t key_length, PyObject *default_value);
+
+static PyObject *
+_dbm_dbm_get(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {"s#|O:get", _keywords, 0};
+    const char *key;
+    Py_ssize_clean_t key_length;
+    PyObject *default_value = Py_None;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &key, &key_length, &default_value)) {
+        goto exit;
+    }
+    return_value = _dbm_dbm_get_impl(self, cls, key, key_length, default_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_dbm_dbm_setdefault__doc__,
+"setdefault($self, key, default=b\'\', /)\n"
+"--\n"
+"\n"
+"Return the value for key if present, otherwise default.\n"
+"\n"
+"If key is not in the database, it is inserted with default as the value.");
+
+#define _DBM_DBM_SETDEFAULT_METHODDEF    \
+    {"setdefault", (PyCFunction)(void(*)(void))_dbm_dbm_setdefault, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_setdefault__doc__},
+
+static PyObject *
+_dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key,
+                         Py_ssize_clean_t key_length,
+                         PyObject *default_value);
+
+static PyObject *
+_dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {"s#|O:setdefault", _keywords, 0};
+    const char *key;
+    Py_ssize_clean_t key_length;
+    PyObject *default_value = NULL;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &key, &key_length, &default_value)) {
+        goto exit;
+    }
+    return_value = _dbm_dbm_setdefault_impl(self, cls, key, key_length, default_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(dbmopen__doc__,
+"open($module, filename, flags=\'r\', mode=0o666, /)\n"
+"--\n"
+"\n"
+"Return a database object.\n"
+"\n"
+"  filename\n"
+"    The filename to open.\n"
+"  flags\n"
+"    How to open the file.  \"r\" for reading, \"w\" for writing, etc.\n"
+"  mode\n"
+"    If creating a new file, the mode bits for the new file\n"
+"    (e.g. os.O_RDWR).");
+
+#define DBMOPEN_METHODDEF    \
+    {"open", (PyCFunction)(void(*)(void))dbmopen, METH_FASTCALL, dbmopen__doc__},
+
+static PyObject *
+dbmopen_impl(PyObject *module, PyObject *filename, const char *flags,
+             int mode);
+
+static PyObject *
+dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *filename;
+    const char *flags = "r";
+    int mode = 438;
+
+    if (!_PyArg_CheckPositional("open", nargs, 1, 3)) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(args[0])) {
+        _PyArg_BadArgument("open", "argument 1", "str", args[0]);
+        goto exit;
+    }
+    if (PyUnicode_READY(args[0]) == -1) {
+        goto exit;
+    }
+    filename = args[0];
+    if (nargs < 2) {
+        goto skip_optional;
+    }
+    if (!PyUnicode_Check(args[1])) {
+        _PyArg_BadArgument("open", "argument 2", "str", args[1]);
+        goto exit;
+    }
+    Py_ssize_t flags_length;
+    flags = PyUnicode_AsUTF8AndSize(args[1], &flags_length);
+    if (flags == NULL) {
+        goto exit;
+    }
+    if (strlen(flags) != (size_t)flags_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+    if (nargs < 3) {
+        goto skip_optional;
+    }
+    mode = _PyLong_AsInt(args[2]);
+    if (mode == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional:
+    return_value = dbmopen_impl(module, filename, flags, mode);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: output=6947b1115df66f7c input=a9049054013a1b77]*/
--- a/3.11/setup.py
+++ b/3.11/setup.py
@@ -548,6 +548,69 @@ class PyBuildExt(build_ext):
 
         # XXX Omitted modules: gl, pure, dl, SGI-specific modules
 
+        # The standard Unix dbm module:
+        if True:
+            dbm_order = "gdbm:ndbm:bdb".split(":")
+            dbmext = None
+            for cand in dbm_order:
+                if cand == "ndbm":
+                    if find_file("ndbm.h", inc_dirs, []) is not None:
+                        # Some systems have -lndbm, others have -lgdbm_compat,
+                        # others don't have either
+                        if self.compiler.find_library_file(lib_dirs,
+                                                               'ndbm'):
+                            ndbm_libs = ['ndbm']
+                        elif self.compiler.find_library_file(lib_dirs,
+                                                             'gdbm_compat'):
+                            ndbm_libs = ['gdbm_compat']
+                        else:
+                            ndbm_libs = []
+                        dbmext = Extension('_dbm', ['Modules/_dbmmodule.c'],
+                                           define_macros=[
+                                               ('HAVE_NDBM_H',None),
+                                               ],
+                                           libraries=ndbm_libs)
+                        break
+
+                elif cand == "gdbm":
+                    if self.compiler.find_library_file(lib_dirs, 'gdbm'):
+                        gdbm_libs = ['gdbm']
+                        if self.compiler.find_library_file(lib_dirs,
+                                                               'gdbm_compat'):
+                            gdbm_libs.append('gdbm_compat')
+                        if find_file("gdbm/ndbm.h", inc_dirs, []) is not None:
+                            dbmext = Extension(
+                                '_dbm', ['Modules/_dbmmodule.c'],
+                                define_macros=[
+                                    ('HAVE_GDBM_NDBM_H', None),
+                                    ],
+                                libraries = gdbm_libs)
+                            break
+                        if find_file("gdbm-ndbm.h", inc_dirs, []) is not None:
+                            dbmext = Extension(
+                                '_dbm', ['Modules/_dbmmodule.c'],
+                                define_macros=[
+                                    ('HAVE_GDBM_DASH_NDBM_H', None),
+                                    ],
+                                libraries = gdbm_libs)
+                            break
+                elif cand == "bdb":
+                    if db_incs is not None:
+                        dbmext = Extension('_dbm', ['Modules/_dbmmodule.c'],
+                                           library_dirs=dblib_dir,
+                                           runtime_library_dirs=dblib_dir,
+                                           include_dirs=db_incs,
+                                           define_macros=[
+                                               ('HAVE_BERKDB_H', None),
+                                               ('DB_DBM_HSEARCH', None),
+                                               ],
+                                           libraries=dblibs)
+                        break
+            if dbmext is not None:
+                exts.append(dbmext)
+            else:
+                missing.append('_dbm')
+
         # Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
         if (True or 'gdbm' in dbm_order and
             self.compiler.find_library_file(lib_dirs, 'gdbm')):
