[Python-checkins] r83406 - in python/branches/py3k: Doc/library/mmap.rst Lib/test/test_mmap.py Misc/NEWS Modules/mmapmodule.c

georg.brandl python-checkins at python.org
Sun Aug 1 16:50:00 CEST 2010


Author: georg.brandl
Date: Sun Aug  1 16:50:00 2010
New Revision: 83406

Log:
#8046: add context manager protocol support to mmap objects.  Also add closed property.

Modified:
   python/branches/py3k/Doc/library/mmap.rst
   python/branches/py3k/Lib/test/test_mmap.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Modules/mmapmodule.c

Modified: python/branches/py3k/Doc/library/mmap.rst
==============================================================================
--- python/branches/py3k/Doc/library/mmap.rst	(original)
+++ python/branches/py3k/Doc/library/mmap.rst	Sun Aug  1 16:50:00 2010
@@ -112,6 +112,18 @@
           map.close()
 
 
+   :class:`mmap` can also be used as a context manager in a :keyword:`with`
+   statement.::
+
+      import mmap
+
+      with mmap.mmap(-1, 13) as map:
+          map.write("Hello world!")
+
+   .. versionadded:: 3.2
+      Context manager support.
+
+
    The next example demonstrates how to create an anonymous map and exchange
    data between the parent and child processes::
 
@@ -132,13 +144,19 @@
 
    Memory-mapped file objects support the following methods:
 
-
    .. method:: close()
 
       Close the file.  Subsequent calls to other methods of the object will
       result in an exception being raised.
 
 
+   .. attribute:: closed
+
+      True if the file is closed.
+
+      .. versionadded:: 3.2
+
+
    .. method:: find(sub[, start[, end]])
 
       Returns the lowest index in the object where the subsequence *sub* is
@@ -236,5 +254,3 @@
       position of the file pointer; the file position is advanced by ``1``. If
       the mmap was created with :const:`ACCESS_READ`, then writing to it will
       throw a :exc:`TypeError` exception.
-
-

Modified: python/branches/py3k/Lib/test/test_mmap.py
==============================================================================
--- python/branches/py3k/Lib/test/test_mmap.py	(original)
+++ python/branches/py3k/Lib/test/test_mmap.py	Sun Aug  1 16:50:00 2010
@@ -586,6 +586,20 @@
                 pass
             m.close()
 
+    def test_context_manager(self):
+        with mmap.mmap(-1, 10) as m:
+            self.assertFalse(m.closed)
+        self.assertTrue(m.closed)
+
+    def test_context_manager_exception(self):
+        # Test that the IOError gets passed through
+        with self.assertRaises(Exception) as exc:
+            with mmap.mmap(-1, 10) as m:
+                raise IOError
+        self.assertIsInstance(exc.exception, IOError,
+                              "wrong exception raised in context manager")
+        self.assertTrue(m.closed, "context manager failed")
+
 
 def test_main():
     run_unittest(MmapTests)

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sun Aug  1 16:50:00 2010
@@ -18,6 +18,12 @@
     - format(complex(-0.0, 2.0), '-') omitted the real part from the output,
     - format(complex(0.0, 2.0), '-') included a sign and parentheses.
 
+Extensions
+----------
+
+- Issue #8046: Add context manager protocol support and .closed property
+  to mmap objects.
+
 Library
 -------
 

Modified: python/branches/py3k/Modules/mmapmodule.c
==============================================================================
--- python/branches/py3k/Modules/mmapmodule.c	(original)
+++ python/branches/py3k/Modules/mmapmodule.c	Sun Aug  1 16:50:00 2010
@@ -651,6 +651,31 @@
     }
 }
 
+static PyObject *
+mmap_closed_get(mmap_object *self)
+{
+#ifdef MS_WINDOWS
+    return PyBool_FromLong(self->map_handle == NULL ? 1 : 0);
+#elif defined(UNIX)
+    return PyBool_FromLong(self->data == NULL ? 1 : 0);
+#endif
+}
+
+static PyObject *
+mmap__enter__method(mmap_object *self, PyObject *args)
+{
+    CHECK_VALID(NULL);
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+}
+
+static PyObject *
+mmap__exit__method(PyObject *self, PyObject *args)
+{
+    return PyObject_CallMethod(self, "close", NULL);
+}
+
 static struct PyMethodDef mmap_object_methods[] = {
     {"close",           (PyCFunction) mmap_close_method,        METH_NOARGS},
     {"find",            (PyCFunction) mmap_find_method,         METH_VARARGS},
@@ -666,9 +691,17 @@
     {"tell",            (PyCFunction) mmap_tell_method,         METH_NOARGS},
     {"write",           (PyCFunction) mmap_write_method,        METH_VARARGS},
     {"write_byte",      (PyCFunction) mmap_write_byte_method,   METH_VARARGS},
+    {"__enter__",       (PyCFunction) mmap__enter__method,      METH_NOARGS},
+    {"__exit__",        (PyCFunction) mmap__exit__method,       METH_VARARGS},
     {NULL,         NULL}       /* sentinel */
 };
 
+static PyGetSetDef mmap_object_getset[] = {
+    {"closed", (getter) mmap_closed_get, NULL, NULL},
+    {NULL}
+};
+
+
 /* Functions for treating an mmap'ed file as a buffer */
 
 static int
@@ -975,7 +1008,7 @@
     0,                                          /* tp_iternext */
     mmap_object_methods,                        /* tp_methods */
     0,                                          /* tp_members */
-    0,                                          /* tp_getset */
+    mmap_object_getset,                         /* tp_getset */
     0,                                          /* tp_base */
     0,                                          /* tp_dict */
     0,                                          /* tp_descr_get */


More information about the Python-checkins mailing list