]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-87595: Support mmap.size() for anonymous mapping on Unix (GH-24781)
authorZackery Spytz <zspytz@gmail.com>
Tue, 2 Sep 2025 20:24:06 +0000 (13:24 -0700)
committerGitHub <noreply@github.com>
Tue, 2 Sep 2025 20:24:06 +0000 (23:24 +0300)
Previously, the size would be returned on Windows and an OSError would
be raised on Unix.

Also, raise ValueError instead of OSError for trackfd=False.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Doc/library/mmap.rst
Lib/test/test_mmap.py
Misc/NEWS.d/next/Library/2021-03-07-16-31-36.bpo-43429.Koa0mf.rst [new file with mode: 0644]
Modules/mmapmodule.c

index 8fca79b23e4e156d67df64ac608d69ebebeb4cf2..5d81477443ca312488d15503a484daf34889b44a 100644 (file)
@@ -312,6 +312,10 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
 
       Return the length of the file, which can be larger than the size of the
       memory-mapped area.
+      For anonymous mapping, return its size.
+
+      .. versionchanged:: next
+         Supports anonymous mapping on Unix.
 
 
    .. method:: tell()
index 38d1a496c30e213b6b90c4d2f16e661251f8cfb7..32881d36dcae100722ed767236633f281889a7de 100644 (file)
@@ -6,7 +6,6 @@ from test.support.import_helper import import_module
 from test.support.os_helper import TESTFN, unlink
 from test.support.script_helper import assert_python_ok
 import unittest
-import errno
 import os
 import re
 import itertools
@@ -282,9 +281,8 @@ class MmapTests(unittest.TestCase):
                         if close_original_fd:
                             f.close()
                         self.assertEqual(len(m), size)
-                        with self.assertRaises(OSError) as err_cm:
+                        with self.assertRaises(ValueError):
                             m.size()
-                        self.assertEqual(err_cm.exception.errno, errno.EBADF)
                         with self.assertRaises(ValueError):
                             m.resize(size * 2)
                         with self.assertRaises(ValueError):
@@ -309,7 +307,7 @@ class MmapTests(unittest.TestCase):
     def test_trackfd_neg1(self):
         size = 64
         with mmap.mmap(-1, size, trackfd=False) as m:
-            with self.assertRaises(OSError):
+            with self.assertRaises(ValueError):
                 m.size()
             with self.assertRaises(ValueError):
                 m.resize(size // 2)
@@ -505,6 +503,7 @@ class MmapTests(unittest.TestCase):
             b = x & 0xff
             m[x] = b
             self.assertEqual(m[x], b)
+        self.assertEqual(m.size(), PAGESIZE)
 
     def test_read_all(self):
         m = mmap.mmap(-1, 16)
diff --git a/Misc/NEWS.d/next/Library/2021-03-07-16-31-36.bpo-43429.Koa0mf.rst b/Misc/NEWS.d/next/Library/2021-03-07-16-31-36.bpo-43429.Koa0mf.rst
new file mode 100644 (file)
index 0000000..a6221ba
--- /dev/null
@@ -0,0 +1,5 @@
+The :meth:`~mmap.mmap.size` method of the :class:`mmap.mmap` class now
+returns the size of an anonymous mapping on both Unix and Windows.
+Previously, the size would be returned on Windows and an :exc:`OSError`
+would be raised on Unix.
+Raise :exc:`ValueError` instead of :exc:`OSError` with ``trackfd=False``.
index 5d5b53717c829caf65bd722e4148fa5d22472c7d..1c300546c33fe8c1155338e0b4baef7d3de487ca 100644 (file)
@@ -740,7 +740,7 @@ mmap_size_method(PyObject *op, PyObject *Py_UNUSED(ignored))
 #endif /* MS_WINDOWS */
 
 #ifdef UNIX
-    {
+    if (self->fd != -1) {
         struct _Py_stat_struct status;
         if (_Py_fstat(self->fd, &status) == -1)
             return NULL;
@@ -750,6 +750,14 @@ mmap_size_method(PyObject *op, PyObject *Py_UNUSED(ignored))
         return PyLong_FromLong(status.st_size);
 #endif
     }
+    else if (self->trackfd) {
+        return PyLong_FromSsize_t(self->size);
+    }
+    else {
+        PyErr_SetString(PyExc_ValueError,
+            "can't get size with trackfd=False");
+        return NULL;
+    }
 #endif /* UNIX */
 }