#8046: add context manager protocol support to mmap objects. Also add closed property.
This commit is contained in:
parent
120d633871
commit
0bccc185b4
|
@ -112,6 +112,18 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
|
|||
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 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
|
|||
|
||||
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 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
|
|||
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.
|
||||
|
||||
|
||||
|
|
|
@ -586,6 +586,20 @@ class MmapTests(unittest.TestCase):
|
|||
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)
|
||||
|
|
|
@ -18,6 +18,12 @@ Core and Builtins
|
|||
- 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
|
||||
-------
|
||||
|
||||
|
|
|
@ -651,6 +651,31 @@ mmap_move_method(mmap_object *self, PyObject *args)
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ static struct PyMethodDef mmap_object_methods[] = {
|
|||
{"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 @@ static PyTypeObject mmap_object_type = {
|
|||
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 */
|
||||
|
|
Loading…
Reference in New Issue