]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
#1087741: make mmap.mmap the type of mmap objects, not a
authorGeorg Brandl <georg@python.org>
Mon, 21 Jan 2008 14:16:46 +0000 (14:16 +0000)
committerGeorg Brandl <georg@python.org>
Mon, 21 Jan 2008 14:16:46 +0000 (14:16 +0000)
factory function. Allow it to be subclassed.

Doc/library/mmap.rst
Misc/NEWS
Modules/mmapmodule.c

index cdc761c9af4a07725ee066d11d37148cb18821d0..70344575b6198c09b7c0d5c872a0cd1fe871f5e7 100644 (file)
@@ -15,7 +15,7 @@ substring by assigning to a slice: ``obj[i1:i2] = '...'``.  You can also read
 and write data starting at the current file position, and :meth:`seek` through
 the file to different positions.
 
-A memory-mapped file is created by the :func:`mmap` function, which is different
+A memory-mapped file is created by the :class:`mmap` constructor, which is different
 on Unix and on Windows.  In either case you must provide a file descriptor for a
 file opened for update. If you wish to map an existing Python file object, use
 its :meth:`fileno` method to obtain the correct value for the *fileno*
@@ -23,7 +23,7 @@ parameter.  Otherwise, you can open the file using the :func:`os.open` function,
 which returns a file descriptor directly (the file still needs to be closed when
 done).
 
-For both the Unix and Windows versions of the function, *access* may be
+For both the Unix and Windows versions of the constructor, *access* may be
 specified as an optional keyword parameter. *access* accepts one of three
 values: :const:`ACCESS_READ`, :const:`ACCESS_WRITE`, or :const:`ACCESS_COPY` to
 specify readonly, write-through or copy-on-write memory respectively. *access*
@@ -39,11 +39,14 @@ not update the underlying file.
    To map anonymous memory, -1 should be passed as the fileno along with the
    length.
 
+.. versionchanged:: 2.6
+   mmap.mmap has formerly been a factory function creating mmap objects. Now 
+   mmap.mmap is the class itself.
 
-.. function:: mmap(fileno, length[, tagname[, access[, offset]]])
+.. class:: mmap(fileno, length[, tagname[, access[, offset]]])
 
    **(Windows version)** Maps *length* bytes from the file specified by the file
-   handle *fileno*, and returns a mmap object.  If *length* is larger than the
+   handle *fileno*, and creates a mmap object.  If *length* is larger than the
    current size of the file, the file is extended to contain *length* bytes.  If
    *length* is ``0``, the maximum length of the map is the current size of the
    file, except that if the file is empty Windows raises an exception (you cannot
@@ -61,12 +64,12 @@ not update the underlying file.
    *offset* must be a multiple of the ALLOCATIONGRANULARITY.
 
 
-.. function:: mmap(fileno, length[, flags[, prot[, access[, offset]]]])
+.. class:: mmap(fileno, length[, flags[, prot[, access[, offset]]]])
    :noindex:
 
    **(Unix version)** Maps *length* bytes from the file specified by the file
    descriptor *fileno*, and returns a mmap object.  If *length* is ``0``, the
-   maximum length of the map will be the current size of the file when :func:`mmap`
+   maximum length of the map will be the current size of the file when :class:`mmap`
    is called.
 
    *flags* specifies the nature of the mapping. :const:`MAP_PRIVATE` creates a
@@ -87,7 +90,7 @@ not update the underlying file.
    be relative to the offset from the beginning of the file. *offset* defaults to 0.
    *offset* must be a multiple of the PAGESIZE or ALLOCATIONGRANULARITY.
    
-   This example shows a simple way of using :func:`mmap`::
+   This example shows a simple way of using :class:`mmap`::
 
       import mmap
 
index e6084787e08bc0ec5b8c22b9fb0e7ad942edab4b..2150ac1aa065f764199c73c7b1528a80030e95a7 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -368,6 +368,8 @@ Core and builtins
 
 Library
 -------
+- #1087741: mmap.mmap is now a class, not a factory function. It is also 
+  subclassable now.
 
 - #1269: fix a bug in pstats.add_callers() and add a unit test file for
   pstats.
index e82014b5982ea83b41fd5f9a69a58e9f00a1ef54..dfbc8fc6e40cf0aa1186436016a9fd880b65aa8e 100644 (file)
@@ -974,6 +974,9 @@ static PyBufferProcs mmap_as_buffer = {
        (charbufferproc)mmap_buffer_getcharbuffer,
 };
 
+static PyObject *
+new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict);
+
 PyDoc_STRVAR(mmap_doc,
 "Windows: mmap(fileno, length[, tagname[, access[, offset]]])\n\
 \n\
@@ -999,7 +1002,7 @@ To map anonymous memory, pass -1 as the fileno (both versions).");
 
 
 static PyTypeObject mmap_object_type = {
-       PyVarObject_HEAD_INIT(0, 0) /* patched in module init */
+       PyVarObject_HEAD_INIT(NULL, 0)
        "mmap.mmap",                            /* tp_name */
        sizeof(mmap_object),                    /* tp_size */
        0,                                      /* tp_itemsize */
@@ -1019,16 +1022,26 @@ static PyTypeObject mmap_object_type = {
        PyObject_GenericGetAttr,                /*tp_getattro*/
        0,                                      /*tp_setattro*/
        &mmap_as_buffer,                        /*tp_as_buffer*/
-       Py_TPFLAGS_HAVE_GETCHARBUFFER,          /*tp_flags*/
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GETCHARBUFFER,               /*tp_flags*/
        mmap_doc,                               /*tp_doc*/
        0,                                      /* tp_traverse */
        0,                                      /* tp_clear */
        0,                                      /* tp_richcompare */
        0,                                      /* tp_weaklistoffset */
-       0,                                      /* tp_iter */
-       0,                                      /* tp_iternext */
+       0,                                      /* tp_iter */
+       0,                                      /* tp_iternext */
        mmap_object_methods,                    /* tp_methods */
-
+       0,                                      /* tp_members */
+       0,                                      /* tp_getset */
+       0,                                      /* tp_base */
+       0,                                      /* tp_dict */
+       0,                                      /* tp_descr_get */
+       0,                                      /* tp_descr_set */
+       0,                                      /* tp_dictoffset */
+       0,                                      /* tp_init */
+       PyType_GenericAlloc,                    /* tp_alloc */
+       new_mmap_object,                        /* tp_new */
+       PyObject_Del,                           /* tp_free */
 };
 
 
@@ -1060,7 +1073,7 @@ _GetMapSize(PyObject *o, const char* param)
 
 #ifdef UNIX
 static PyObject *
-new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
+new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
 {
 #ifdef HAVE_FSTAT
        struct stat st;
@@ -1128,7 +1141,7 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
                }
        }
 #endif
-       m_obj = PyObject_New(mmap_object, &mmap_object_type);
+       m_obj = (mmap_object *)type->tp_alloc(type, 0);
        if (m_obj == NULL) {return NULL;}
        m_obj->data = NULL;
        m_obj->size = (size_t) map_size;
@@ -1182,7 +1195,7 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
 
 #ifdef MS_WINDOWS
 static PyObject *
-new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
+new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
 {
        mmap_object *m_obj;
        PyObject *map_size_obj = NULL, *offset_obj = NULL;
@@ -1250,7 +1263,7 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
                lseek(fileno, 0, SEEK_SET);
        }
 
-       m_obj = PyObject_New(mmap_object, &mmap_object_type);
+       m_obj = (mmap_object *)type->tp_alloc(type, 0);
        if (m_obj == NULL)
                return NULL;
        /* Set every field to an invalid marker, so we can safely
@@ -1364,13 +1377,6 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
 }
 #endif /* MS_WINDOWS */
 
-/* List of functions exported by this module */
-static struct PyMethodDef mmap_functions[] = {
-       {"mmap",        (PyCFunction) new_mmap_object,
-        METH_VARARGS|METH_KEYWORDS, mmap_doc},
-       {NULL,          NULL}        /* Sentinel */
-};
-
 static void
 setint(PyObject *d, const char *name, long value)
 {
@@ -1381,14 +1387,14 @@ setint(PyObject *d, const char *name, long value)
 }
 
 PyMODINIT_FUNC
-       initmmap(void)
+initmmap(void)
 {
        PyObject *dict, *module;
 
-       /* Patch the object type */
-       Py_TYPE(&mmap_object_type) = &PyType_Type;
+       if (PyType_Ready(&mmap_object_type) < 0)
+               return;
 
-       module = Py_InitModule("mmap", mmap_functions);
+       module = Py_InitModule("mmap", NULL);
        if (module == NULL)
                return;
        dict = PyModule_GetDict(module);
@@ -1396,6 +1402,7 @@ PyMODINIT_FUNC
                return;
        mmap_module_error = PyExc_EnvironmentError;
        PyDict_SetItemString(dict, "error", mmap_module_error);
+       PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type);
 #ifdef PROT_EXEC
        setint(dict, "PROT_EXEC", PROT_EXEC);
 #endif