]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111835: Add seekable method to mmap.mmap (gh-111852)
authorDonghee Na <donghee.na@python.org>
Thu, 9 Nov 2023 11:13:35 +0000 (11:13 +0000)
committerGitHub <noreply@github.com>
Thu, 9 Nov 2023 11:13:35 +0000 (20:13 +0900)
Doc/library/mmap.rst
Doc/whatsnew/3.13.rst
Lib/test/test_mmap.py
Misc/NEWS.d/next/Library/2023-11-08-23-32-03.gh-issue-111835.ufFiuW.rst [new file with mode: 0644]
Modules/mmapmodule.c

index 4ca7a64451d4c729111e65912a1c09ceb3258361..3fa69e717329e445146e24101a1effc17154d01c 100644 (file)
@@ -285,6 +285,14 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
       values are ``os.SEEK_CUR`` or ``1`` (seek relative to the current
       position) and ``os.SEEK_END`` or ``2`` (seek relative to the file's end).
 
+      .. versionchanged:: 3.13
+         Return the new absolute position instead of ``None``.
+
+   .. method:: seekable()
+
+      Return whether the file supports seeking, and the return value is always ``True``.
+
+      .. versionadded:: 3.13
 
    .. method:: size()
 
index 428b648d9e1912aeb004cf47eccfb13ef01b4243..ae3c88d28d73a08ae707a2f053b90086bc8fa0c0 100644 (file)
@@ -198,6 +198,14 @@ ipaddress
 * Add the :attr:`ipaddress.IPv4Address.ipv6_mapped` property, which returns the IPv4-mapped IPv6 address.
   (Contributed by Charles Machalow in :gh:`109466`.)
 
+mmap
+----
+
+* The :class:`mmap.mmap` class now has an :meth:`~mmap.mmap.seekable` method
+  that can be used where it requires a file-like object with seekable and
+  the :meth:`~mmap.mmap.seek` method return the new absolute position.
+  (Contributed by Donghee Na and Sylvie Liberman in :gh:`111835`.)
+
 opcode
 ------
 
index dfcf3039422af5e0d0328c2b1c5d022a4a3d6a02..866ede5b83dff08a5eb1ece1c0d378289982f0eb 100644 (file)
@@ -93,11 +93,12 @@ class MmapTests(unittest.TestCase):
             self.assertEqual(end, PAGESIZE + 6)
 
         # test seeking around (try to overflow the seek implementation)
-        m.seek(0,0)
+        self.assertTrue(m.seekable())
+        self.assertEqual(m.seek(0, 0), 0)
         self.assertEqual(m.tell(), 0)
-        m.seek(42,1)
+        self.assertEqual(m.seek(42, 1), 42)
         self.assertEqual(m.tell(), 42)
-        m.seek(0,2)
+        self.assertEqual(m.seek(0, 2), len(m))
         self.assertEqual(m.tell(), len(m))
 
         # Try to seek to negative position...
@@ -162,7 +163,7 @@ class MmapTests(unittest.TestCase):
 
             # Ensuring that readonly mmap can't be write() to
             try:
-                m.seek(0,0)
+                m.seek(0, 0)
                 m.write(b'abc')
             except TypeError:
                 pass
@@ -171,7 +172,7 @@ class MmapTests(unittest.TestCase):
 
             # Ensuring that readonly mmap can't be write_byte() to
             try:
-                m.seek(0,0)
+                m.seek(0, 0)
                 m.write_byte(b'd')
             except TypeError:
                 pass
diff --git a/Misc/NEWS.d/next/Library/2023-11-08-23-32-03.gh-issue-111835.ufFiuW.rst b/Misc/NEWS.d/next/Library/2023-11-08-23-32-03.gh-issue-111835.ufFiuW.rst
new file mode 100644 (file)
index 0000000..5d06c22
--- /dev/null
@@ -0,0 +1,4 @@
+The :class:`mmap.mmap` class now has an :meth:`~mmap.mmap.seekable` method
+that can be used where it requires a file-like object with seekable and
+the :meth:`~mmap.mmap.seek` method return the new absolute position.
+Patch by Donghee Na.
index d11200a40425518c42927c67e3ba1a2aeaa7d294..66ed0b8efb775c126c09013538ce53d6f863c655 100644 (file)
@@ -171,7 +171,7 @@ mmap_object_dealloc(mmap_object *m_obj)
 }
 
 static PyObject *
-mmap_close_method(mmap_object *self, PyObject *unused)
+mmap_close_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
 {
     if (self->exports > 0) {
         PyErr_SetString(PyExc_BufferError, "cannot close "\
@@ -260,7 +260,7 @@ do {                                                                    \
 
 static PyObject *
 mmap_read_byte_method(mmap_object *self,
-                      PyObject *unused)
+                      PyObject *Py_UNUSED(ignored))
 {
     CHECK_VALID(NULL);
     if (self->pos >= self->size) {
@@ -272,7 +272,7 @@ mmap_read_byte_method(mmap_object *self,
 
 static PyObject *
 mmap_read_line_method(mmap_object *self,
-                      PyObject *unused)
+                      PyObject *Py_UNUSED(ignored))
 {
     Py_ssize_t remaining;
     char *start, *eol;
@@ -460,7 +460,7 @@ mmap_write_byte_method(mmap_object *self,
 
 static PyObject *
 mmap_size_method(mmap_object *self,
-                 PyObject *unused)
+                 PyObject *Py_UNUSED(ignored))
 {
     CHECK_VALID(NULL);
 
@@ -657,7 +657,7 @@ mmap_resize_method(mmap_object *self,
 }
 
 static PyObject *
-mmap_tell_method(mmap_object *self, PyObject *unused)
+mmap_tell_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
 {
     CHECK_VALID(NULL);
     return PyLong_FromSize_t(self->pos);
@@ -729,7 +729,7 @@ mmap_seek_method(mmap_object *self, PyObject *args)
         if (where > self->size || where < 0)
             goto onoutofrange;
         self->pos = where;
-        Py_RETURN_NONE;
+        return PyLong_FromSsize_t(self->pos);
     }
 
   onoutofrange:
@@ -737,6 +737,12 @@ mmap_seek_method(mmap_object *self, PyObject *args)
     return NULL;
 }
 
+static PyObject *
+mmap_seekable_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
+{
+    Py_RETURN_TRUE;
+}
+
 static PyObject *
 mmap_move_method(mmap_object *self, PyObject *args)
 {
@@ -835,7 +841,7 @@ mmap__repr__method(PyObject *self)
 
 #ifdef MS_WINDOWS
 static PyObject *
-mmap__sizeof__method(mmap_object *self, void *unused)
+mmap__sizeof__method(mmap_object *self, void *Py_UNUSED(ignored))
 {
     size_t res = _PyObject_SIZE(Py_TYPE(self));
     if (self->tagname) {
@@ -905,6 +911,7 @@ static struct PyMethodDef mmap_object_methods[] = {
     {"readline",        (PyCFunction) mmap_read_line_method,    METH_NOARGS},
     {"resize",          (PyCFunction) mmap_resize_method,       METH_VARARGS},
     {"seek",            (PyCFunction) mmap_seek_method,         METH_VARARGS},
+    {"seekable",        (PyCFunction) mmap_seekable_method,     METH_NOARGS},
     {"size",            (PyCFunction) mmap_size_method,         METH_NOARGS},
     {"tell",            (PyCFunction) mmap_tell_method,         METH_NOARGS},
     {"write",           (PyCFunction) mmap_write_method,        METH_VARARGS},