https://github.com/python/cpython/commit/0cec424af5904b3d23ad6e3c6d1a27f89d238d64
commit: 0cec424af5904b3d23ad6e3c6d1a27f89d238d64
branch: main
author: Serhiy Storchaka <storch...@gmail.com>
committer: serhiy-storchaka <storch...@gmail.com>
date: 2025-06-02T21:08:26+03:00
summary:

gh-66234: Add flag to disable the use of mmap in dbm.gnu (GH-135005)

This may harm performance, but improve crash tolerance.

files:
A Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst
M Doc/library/dbm.rst
M Doc/whatsnew/3.15.rst
M Lib/test/test_dbm_gnu.py
M Modules/_gdbmmodule.c

diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst
index 6f548fbb1b39d8..39e287b15214e4 100644
--- a/Doc/library/dbm.rst
+++ b/Doc/library/dbm.rst
@@ -254,6 +254,9 @@ functionality like crash tolerance.
       * ``'s'``: Synchronized mode.
         Changes to the database will be written immediately to the file.
       * ``'u'``: Do not lock database.
+      * ``'m'``: Do not use :manpage:`mmap(2)`.
+        This may harm performance, but improve crash tolerance.
+        .. versionadded:: next
 
       Not all flags are valid for all versions of GDBM.
       See the :data:`open_flags` member for a list of supported flag 
characters.
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index a27a17afdba2a8..2fe33c4c535919 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -96,6 +96,10 @@ dbm
   which allow to recover unused free space previously occupied by deleted 
entries.
   (Contributed by Andrea Oliveri in :gh:`134004`.)
 
+* Add the ``'m'`` flag for :func:`dbm.gnu.open` which allows to disable
+  the use of :manpage:`mmap(2)`.
+  This may harm performance, but improve crash tolerance.
+  (Contributed by Serhiy Storchaka in :gh:`66234`.)
 
 difflib
 -------
diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py
index 66268c42a300b5..e0b988b7b95bbd 100644
--- a/Lib/test/test_dbm_gnu.py
+++ b/Lib/test/test_dbm_gnu.py
@@ -74,12 +74,12 @@ def test_flags(self):
         # Test the flag parameter open() by trying all supported flag modes.
         all = set(gdbm.open_flags)
         # Test standard flags (presumably "crwn").
-        modes = all - set('fsu')
+        modes = all - set('fsum')
         for mode in sorted(modes):  # put "c" mode first
             self.g = gdbm.open(filename, mode)
             self.g.close()
 
-        # Test additional flags (presumably "fsu").
+        # Test additional flags (presumably "fsum").
         flags = all - set('crwn')
         for mode in modes:
             for flag in flags:
@@ -217,6 +217,29 @@ def test_localized_error(self):
             create_empty_file(os.path.join(d, 'test'))
             self.assertRaises(gdbm.error, gdbm.open, filename, 'r')
 
+    @unittest.skipUnless('m' in gdbm.open_flags, "requires 'm' in open_flags")
+    def test_nommap_no_crash(self):
+        self.g = g = gdbm.open(filename, 'nm')
+        os.truncate(filename, 0)
+
+        g.get(b'a', b'c')
+        g.keys()
+        g.firstkey()
+        g.nextkey(b'a')
+        with self.assertRaises(KeyError):
+            g[b'a']
+        with self.assertRaises(gdbm.error):
+            len(g)
+
+        with self.assertRaises(gdbm.error):
+            g[b'a'] = b'c'
+        with self.assertRaises(gdbm.error):
+            del g[b'a']
+        with self.assertRaises(gdbm.error):
+            g.setdefault(b'a', b'c')
+        with self.assertRaises(gdbm.error):
+            g.reorganize()
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst 
b/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst
new file mode 100644
index 00000000000000..1defb9a72e04e7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst
@@ -0,0 +1,3 @@
+Add the ``'m'`` flag for :func:`dbm.gnu.open` which allows to disable the
+use of :manpage:`mmap(2)`. This may harm performance, but improve crash
+tolerance.
diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c
index 9c402e20e513b9..6a4939512b22fc 100644
--- a/Modules/_gdbmmodule.c
+++ b/Modules/_gdbmmodule.c
@@ -813,6 +813,11 @@ dbmopen_impl(PyObject *module, PyObject *filename, const 
char *flags,
             case 'u':
                 iflags |= GDBM_NOLOCK;
                 break;
+#endif
+#ifdef GDBM_NOMMAP
+            case 'm':
+                iflags |= GDBM_NOMMAP;
+                break;
 #endif
             default:
                 PyErr_Format(state->gdbm_error,
@@ -846,6 +851,9 @@ static const char gdbmmodule_open_flags[] = "rwcn"
 #endif
 #ifdef GDBM_NOLOCK
                                      "u"
+#endif
+#ifdef GDBM_NOMMAP
+                                     "m"
 #endif
                                      ;
 

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: arch...@mail-archive.com

Reply via email to