[Python-checkins] cpython: Issue #12021: Make mmap's read() method argument optional. Patch by Petri

charles-francois.natali python-checkins at python.org
Wed Jun 8 19:18:35 CEST 2011


http://hg.python.org/cpython/rev/964d0d65a2a9
changeset:   70712:964d0d65a2a9
user:        Charles-François Natali <neologix at free.fr>
date:        Wed Jun 08 19:18:14 2011 +0200
summary:
  Issue #12021: Make mmap's read() method argument optional. Patch by Petri
Lehtinen.

files:
  Doc/library/mmap.rst  |  12 ++++++++----
  Lib/test/test_mmap.py |  29 +++++++++++++++++++++++++++++
  Misc/ACKS             |   1 +
  Misc/NEWS             |   3 +++
  Modules/mmapmodule.c  |  26 ++++++++++++++++++++++++--
  5 files changed, 65 insertions(+), 6 deletions(-)


diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst
--- a/Doc/library/mmap.rst
+++ b/Doc/library/mmap.rst
@@ -190,12 +190,16 @@
       move will raise a :exc:`TypeError` exception.
 
 
-   .. method:: read(num)
+   .. method:: read([n])
 
-      Return a :class:`bytes` containing up to *num* bytes starting from the
-      current file position; the file position is updated to point after the
-      bytes that were returned.
+      Return a :class:`bytes` containing up to *n* bytes starting from the
+      current file position. If the argument is omitted, *None* or negative,
+      return all bytes from the current file position to the end of the
+      mapping. The file position is updated to point after the bytes that were
+      returned.
 
+      .. versionchanged:: 3.3
+         Argument can be omitted or *None*.
 
    .. method:: read_byte()
 
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -417,6 +417,35 @@
             m[x] = b
             self.assertEqual(m[x], b)
 
+    def test_read_all(self):
+        m = mmap.mmap(-1, 16)
+        self.addCleanup(m.close)
+
+        # With no parameters, or None or a negative argument, reads all
+        m.write(bytes(range(16)))
+        m.seek(0)
+        self.assertEqual(m.read(), bytes(range(16)))
+        m.seek(8)
+        self.assertEqual(m.read(), bytes(range(8, 16)))
+        m.seek(16)
+        self.assertEqual(m.read(), b'')
+        m.seek(3)
+        self.assertEqual(m.read(None), bytes(range(3, 16)))
+        m.seek(4)
+        self.assertEqual(m.read(-1), bytes(range(4, 16)))
+        m.seek(5)
+        self.assertEqual(m.read(-2), bytes(range(5, 16)))
+        m.seek(9)
+        self.assertEqual(m.read(-42), bytes(range(9, 16)))
+
+    def test_read_invalid_arg(self):
+        m = mmap.mmap(-1, 16)
+        self.addCleanup(m.close)
+
+        self.assertRaises(TypeError, m.read, 'foo')
+        self.assertRaises(TypeError, m.read, 5.5)
+        self.assertRaises(TypeError, m.read, [1, 2, 3])
+
     def test_extended_getslice(self):
         # Test extended slicing by comparing with list slicing.
         s = bytes(reversed(range(256)))
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -548,6 +548,7 @@
 Kip Lehman
 Joerg Lehmann
 Robert Lehmann
+Petri Lehtinen
 Luke Kenneth Casson Leighton
 Marc-Andre Lemburg
 John Lenton
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -187,6 +187,9 @@
 Library
 -------
 
+- Issue #12021: Make mmap's read() method argument optional. Patch by Petri
+  Lehtinen.
+
 - Issue #9205: concurrent.futures.ProcessPoolExecutor now detects killed
   children and raises BrokenProcessPool in such a situation.  Previously it
   would reliably freeze/deadlock.
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -240,15 +240,37 @@
     return result;
 }
 
+/* Basically the "n" format code with the ability to turn None into -1. */
+static int
+mmap_convert_ssize_t(PyObject *obj, void *result) {
+    Py_ssize_t limit;
+    if (obj == Py_None) {
+        limit = -1;
+    }
+    else if (PyNumber_Check(obj)) {
+        limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError);
+        if (limit == -1 && PyErr_Occurred())
+            return 0;
+    }
+    else {
+        PyErr_Format(PyExc_TypeError,
+                     "integer argument expected, got '%.200s'",
+                     Py_TYPE(obj)->tp_name);
+        return 0;
+    }
+    *((Py_ssize_t *)result) = limit;
+    return 1;
+}
+
 static PyObject *
 mmap_read_method(mmap_object *self,
                  PyObject *args)
 {
-    Py_ssize_t num_bytes, n;
+    Py_ssize_t num_bytes = -1, n;
     PyObject *result;
 
     CHECK_VALID(NULL);
-    if (!PyArg_ParseTuple(args, "n:read", &num_bytes))
+    if (!PyArg_ParseTuple(args, "|O&:read", mmap_convert_ssize_t, &num_bytes))
         return(NULL);
 
     /* silently 'adjust' out-of-range requests */

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list