Issue #12021: Make mmap's read() method argument optional. Patch by Petri
Lehtinen.
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index 38f6157..ab12e2c 100644
--- 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 */