Skip to content

Commit 8c45634

Browse files
ZackerySpytzserhiy-storchaka
authored andcommitted
pythongh-87595: Support mmap.size() for anonymous mapping on Unix (pythonGH-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. (cherry picked from commit 32032ee) Co-authored-by: Zackery Spytz <[email protected]> Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 3a2e436 commit 8c45634

File tree

4 files changed

+21
-5
lines changed

4 files changed

+21
-5
lines changed

Doc/library/mmap.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,10 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
312312

313313
Return the length of the file, which can be larger than the size of the
314314
memory-mapped area.
315+
For anonymous mapping, return its size.
316+
317+
.. versionchanged:: next
318+
Supports anonymous mapping on Unix.
315319

316320

317321
.. method:: tell()

Lib/test/test_mmap.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from test.support.os_helper import TESTFN, unlink
66
from test.support.script_helper import assert_python_ok
77
import unittest
8-
import errno
98
import os
109
import re
1110
import itertools
@@ -281,9 +280,8 @@ def test_trackfd_parameter(self):
281280
if close_original_fd:
282281
f.close()
283282
self.assertEqual(len(m), size)
284-
with self.assertRaises(OSError) as err_cm:
283+
with self.assertRaises(ValueError):
285284
m.size()
286-
self.assertEqual(err_cm.exception.errno, errno.EBADF)
287285
with self.assertRaises(ValueError):
288286
m.resize(size * 2)
289287
with self.assertRaises(ValueError):
@@ -308,7 +306,7 @@ def test_trackfd_parameter(self):
308306
def test_trackfd_neg1(self):
309307
size = 64
310308
with mmap.mmap(-1, size, trackfd=False) as m:
311-
with self.assertRaises(OSError):
309+
with self.assertRaises(ValueError):
312310
m.size()
313311
with self.assertRaises(ValueError):
314312
m.resize(size // 2)
@@ -504,6 +502,7 @@ def test_anonymous(self):
504502
b = x & 0xff
505503
m[x] = b
506504
self.assertEqual(m[x], b)
505+
self.assertEqual(m.size(), PAGESIZE)
507506

508507
def test_read_all(self):
509508
m = mmap.mmap(-1, 16)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The :meth:`~mmap.mmap.size` method of the :class:`mmap.mmap` class now
2+
returns the size of an anonymous mapping on both Unix and Windows.
3+
Previously, the size would be returned on Windows and an :exc:`OSError`
4+
would be raised on Unix.
5+
Raise :exc:`ValueError` instead of :exc:`OSError` with ``trackfd=False``.

Modules/mmapmodule.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ mmap_size_method(mmap_object *self,
728728
#endif /* MS_WINDOWS */
729729

730730
#ifdef UNIX
731-
{
731+
if (self->fd != -1) {
732732
struct _Py_stat_struct status;
733733
if (_Py_fstat(self->fd, &status) == -1)
734734
return NULL;
@@ -738,6 +738,14 @@ mmap_size_method(mmap_object *self,
738738
return PyLong_FromLong(status.st_size);
739739
#endif
740740
}
741+
else if (self->trackfd) {
742+
return PyLong_FromSsize_t(self->size);
743+
}
744+
else {
745+
PyErr_SetString(PyExc_ValueError,
746+
"can't get size with trackfd=False");
747+
return NULL;
748+
}
741749
#endif /* UNIX */
742750
}
743751

0 commit comments

Comments
 (0)