[Python-checkins] r54997 - peps/trunk/pep-0000.txt peps/trunk/pep-3121.txt
martin.v.loewis
python-checkins at python.org
Fri Apr 27 10:27:25 CEST 2007
Author: martin.v.loewis
Date: Fri Apr 27 10:27:24 2007
New Revision: 54997
Added:
peps/trunk/pep-3121.txt (contents, props changed)
Modified:
peps/trunk/pep-0000.txt
Log:
Add PEP 3121.
Modified: peps/trunk/pep-0000.txt
==============================================================================
--- peps/trunk/pep-0000.txt (original)
+++ peps/trunk/pep-0000.txt Fri Apr 27 10:27:24 2007
@@ -118,6 +118,7 @@
S 3118 Revising the buffer protocol Oliphant, Banks
S 3119 Introducing Abstract Base Classes GvR, Talin
S 3120 Using UTF-8 as the default source encoding von Löwis
+ S 3121 Module Initialization and finalization von Löwis
S 3141 A Type Hierarchy for Numbers Yasskin
Finished PEPs (done, implemented in Subversion)
@@ -476,6 +477,7 @@
S 3118 Revising the buffer protocol Oliphant, Banks
S 3119 Introducing Abstract Base Classes GvR, Talin
S 3120 Using UTF-8 as the default source encoding von Löwis
+ S 3121 Module Initialization and finalization von Löwis
S 3141 A Type Hierarchy for Numbers Yasskin
Added: peps/trunk/pep-3121.txt
==============================================================================
--- (empty file)
+++ peps/trunk/pep-3121.txt Fri Apr 27 10:27:24 2007
@@ -0,0 +1,220 @@
+PEP: 3121
+Title: Module Initialization and finalization
+Version: $Revision: 54994 $
+Last-Modified: $Date: 2007-04-27 08:34:37 +0200 (Fr, 27 Apr 2007) $
+Author: Martin v. Löwis <martin at v.loewis.de>
+Status: Draft
+Type: Standards Track
+Content-Type: text/x-rst
+Created: 27-Apr-2007
+Python-Version: 3.0
+Post-History:
+
+Abstract
+========
+
+Module initialization currently has a few deficiencies. There is no
+cleanup for modules, the entry point name might give naming conflicts,
+the entry functions don't follow the usual calling convention, and
+multiple interpreters are not supported well. This PEP addresses these
+issues.
+
+Module Finalization
+===================
+
+Currently, C modules are initialized usually once and then "live"
+forever. The only exception is when Py_Finalize() is called: then
+the initialization routine is invoked a second time. This is bad
+from a resource management point of view: memory and other resources
+might get allocated each time initialization is called, but there
+is no way to reclaim them. As a result, there is currently no
+way to completely release all resources Python has allocated.
+
+Entry point name conflicts
+==========================
+
+The entry point is currently called init<module>. This might conflict
+with other symbols also called init<something>. In particular,
+initsocket is known to have conflicted in the past (this specific
+problem got resolved as a side effect of renaming the module to
+_socket).
+
+Entry point signature
+=====================
+
+The entry point is currently a procedure (returning void). This
+deviates from the usual calling conventions; callers can find out
+whether there was an error during initialization only by checking
+PyErr_Occurred. The entry point should return a PyObject*, which will
+be the module created, or NULL in case of an exception.
+
+Multiple Interpreters
+=====================
+
+Currently, extension modules share their state across all
+interpreters. This allows for undesirable information leakage across
+interpreters: one script could permanently corrupt objects in an
+extension module, possibly breaking all scripts in other interpreters.
+
+Specification
+=============
+
+The module initialization routines change their signature
+to::
+
+ PyObject *PyInit_<modulename>()
+
+The initialization routine will be invoked once per
+interpreter, when the module is imported. It should
+return a new module object each time.
+
+In order to store per-module state in C variables,
+each module object will contain a block of memory
+that is interpreted only by the module. The amount
+of memory used for the module is specified at
+the point of creation of the module.
+
+In addition to the initialization function, a module
+may implement a number of additional callback
+function, which are invoked when the module's
+tp_traverse, tp_clear, and tp_free functions are
+invoked, and when the module is reloaded.
+
+The entire module definition is combined in a struct
+PyModuleDef::
+
+ struct PyModuleDef{
+ PyModuleDef_Base m_base; /* To be filled out by the interpreter */
+ Py_ssize_t m_size; /* Size of per-module data */
+ PyMethodDef *m_methods;
+ inquiry m_reload;
+ traverseproc m_traverse;
+ inquiry m_clear;
+ freefunc m_free;
+ };
+
+Creation of a module is changed to expect an optional
+PyModuleDef*. The module state will be
+null-initialized.
+
+Each module method with be passed the module object
+as the first parameter. To access the module data,
+a function::
+
+ void* PyModule_GetData(PyObject*);
+
+will be provided. In addition, to lookup a module
+more efficiently than going through sys.modules,
+a function::
+
+ PyObject* PyState_FindModule(struct PyModuleDef*);
+
+will be provided. This lookup function will use an
+index located in the m_base field, to find the
+module by index, not by name.
+
+As all Python objects should be controlled through
+the Python memory management, usage of "static"
+type objects is discouraged, unless the type object
+itself has no memory-managed state. To simplify
+definition of heap types, a new method::
+
+ PyTypeObject* PyType_Copy(PyTypeObject*);
+
+is added.
+
+Example
+=======
+
+xxmodule.c would be changed to remove the initxx
+function, and add the following code instead::
+
+ struct xxstate{
+ PyObject *ErrorObject;
+ PyObject *Xxo_Type;
+ };
+
+ #define xxstate(o) ((struct xxstate*)PyModule_GetState(o))
+
+ static int xx_traverse(PyObject *m, visitproc v,
+ void *arg)
+ {
+ Py_VISIT(xxstate(m)->ErrorObject);
+ Py_VISIT(xxstate(m)->Xxo_Type);
+ return 0;
+ }
+
+ static int xx_clear(PyObject *m)
+ {
+ Py_CLEAR(xxstate(m)->ErrorObject);
+ Py_CLEAR(xxstate(m)->Xxo_Type);
+ return 0;
+ }
+
+ static struct PyModuleDef xxmodule = {
+ {}, /* m_base */
+ sizeof(struct xxstate),
+ &xx_methods,
+ 0, /* m_reload */
+ xx_traverse,
+ xx_clear,
+ 0, /* m_free - not needed, since all is done in m_clear */
+ }
+
+ PyObject*
+ PyInit_xx()
+ {
+ PyObject *res = PyModule_New("xx", &xxmodule);
+ if (!res) return NULL;
+ xxstate(res)->ErrorObject = PyErr_NewException("xx.error, NULL, NULL);
+ if (!xxstate(res)->ErrorObject) {
+ Py_DECREF(res);
+ return NULL;
+ }
+ xxstate(res)->XxoType = PyType_Copy(&Xxo_Type);
+ if (!xxstate(res)->Xxo_Type) {
+ Py_DECREF(res);
+ return NULL;
+ }
+ return res;
+ }
+
+
+Discussion
+==========
+
+Tim Peters reports in [1]_ that PythonLabs considered such a feature
+at one point, and lists the following additional hooks which aren't
+currently supported in this PEP:
+
+ * when the module object is deleted from sys.modules
+
+ * when Py_Finalize is called
+
+ * when Python exits
+
+ * when the Python DLL is unloaded (Windows only)
+
+
+References
+==========
+
+.. [1] Tim Peters, reporting earlier conversation about such a feature
+ http://mail.python.org/pipermail/python-3000/2006-April/000726.html
+
+
+Copyright
+=========
+
+This document has been placed in the public domain.
+
+
+
+..
+ Local Variables:
+ mode: indented-text
+ indent-tabs-mode: nil
+ sentence-end-double-space: t
+ fill-column: 70
+ coding: utf-8
+ End:
More information about the Python-checkins
mailing list