https://github.com/python/cpython/commit/32032ee376fe20670e9a35e56beff48e59201261
commit: 32032ee376fe20670e9a35e56beff48e59201261
branch: main
author: Zackery Spytz <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-09-02T23:24:06+03:00
summary:

gh-87595: Support mmap.size() for anonymous mapping on Unix (GH-24781)

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 <[email protected]>

files:
A Misc/NEWS.d/next/Library/2021-03-07-16-31-36.bpo-43429.Koa0mf.rst
M Doc/library/mmap.rst
M Lib/test/test_mmap.py
M Modules/mmapmodule.c

diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst
index 8fca79b23e4e15..5d81477443ca31 100644
--- a/Doc/library/mmap.rst
+++ b/Doc/library/mmap.rst
@@ -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()
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index 38d1a496c30e21..32881d36dcae10 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -6,7 +6,6 @@
 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 @@ def test_trackfd_parameter(self):
                         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 @@ def test_trackfd_parameter(self):
     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 @@ def test_anonymous(self):
             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
index 00000000000000..a6221ba9c88585
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-03-07-16-31-36.bpo-43429.Koa0mf.rst
@@ -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``.
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index 5d5b53717c829c..1c300546c33fe8 100644
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -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 */
 }
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to