From bd1ada6df35f29069fc478ce3b0fee3372df075a Mon Sep 17 00:00:00 2001 From: AN Long Date: Tue, 30 Sep 2025 18:08:50 +0900 Subject: [PATCH] gh-138092: Allow calling mmap.flush with offset only (#138093) --- Doc/library/mmap.rst | 9 +++++++-- Lib/test/test_mmap.py | 12 ++++++++++++ .../2025-08-24-02-04-32.gh-issue-138092.V4-wTO.rst | 2 ++ Modules/mmapmodule.c | 8 ++++++-- 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-08-24-02-04-32.gh-issue-138092.V4-wTO.rst diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index bd3f7229bdaf..b6ffb5cebc02 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -212,8 +212,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length Writable :term:`bytes-like object` is now accepted. - .. method:: flush() - flush(offset, size, /) + .. method:: flush([offset[, size]]) Flushes changes made to the in-memory copy of a file back to disk. Without use of this call there is no guarantee that changes are written back before @@ -230,6 +229,12 @@ To map anonymous memory, -1 should be passed as the fileno along with the length on error under Windows. A zero value was returned on success; an exception was raised on error under Unix. + .. versionchanged:: next + Allow specifying *offset* without *size*. Previously, both *offset* + and *size* parameters were required together. Now *offset* can be + specified alone, and the flush operation will extend from *offset* + to the end of the mmap. + .. method:: madvise(option[, start[, length]]) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 75ea1a671b67..0571eed23f72 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -1145,6 +1145,18 @@ class MmapTests(unittest.TestCase): self.assertEqual(stdout.strip(), b'') self.assertEqual(stderr.strip(), b'') + def test_flush_parameters(self): + with open(TESTFN, 'wb+') as f: + f.write(b'x' * PAGESIZE * 3) + f.flush() + + m = mmap.mmap(f.fileno(), PAGESIZE * 3) + self.addCleanup(m.close) + + m.flush() + m.flush(PAGESIZE) + m.flush(PAGESIZE, PAGESIZE) + class LargeMmapTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2025-08-24-02-04-32.gh-issue-138092.V4-wTO.rst b/Misc/NEWS.d/next/Library/2025-08-24-02-04-32.gh-issue-138092.V4-wTO.rst new file mode 100644 index 000000000000..21c28c49628c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-08-24-02-04-32.gh-issue-138092.V4-wTO.rst @@ -0,0 +1,2 @@ +Fixed a bug in :meth:`mmap.mmap.flush` where calling with only an offset +parameter would fail. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 8caadde8ae21..41d117162882 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -933,11 +933,15 @@ static PyObject * mmap_flush_method(PyObject *op, PyObject *args) { Py_ssize_t offset = 0; + Py_ssize_t size = -1; mmap_object *self = mmap_object_CAST(op); - Py_ssize_t size = self->size; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size)) + if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size)) { return NULL; + } + if (size == -1) { + size = self->size - offset; + } if (size < 0 || offset < 0 || self->size - offset < size) { PyErr_SetString(PyExc_ValueError, "flush values out of range"); return NULL; -- 2.47.3