PEP 489: Multi-phase extension module initialization
Known limitations of the current implementation:
- documentation changes are incomplete
- there's a reference leak I haven't tracked down yet
The leak is most visible by running:
./python -m test -R3:3 test_importlib
However, you can also see it by running:
./python -X showrefcount
Importing the array or _testmultiphase modules, and
then deleting them from both sys.modules and the local
namespace shows significant increases in the total
number of active references each cycle. By contrast,
with _testcapi (which continues to use single-phase
initialisation) the global refcounts stabilise after
a couple of cycles.
diff --git a/Include/moduleobject.h b/Include/moduleobject.h
index f119364..e68d144 100644
--- a/Include/moduleobject.h
+++ b/Include/moduleobject.h
@@ -30,6 +30,9 @@
PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*);
PyAPI_FUNC(void*) PyModule_GetState(PyObject*);
+PyAPI_FUNC(PyObject *) PyModuleDef_Init(struct PyModuleDef*);
+PyTypeObject PyModuleDef_Type;
+
typedef struct PyModuleDef_Base {
PyObject_HEAD
PyObject* (*m_init)(void);
@@ -44,18 +47,29 @@
NULL, /* m_copy */ \
}
+typedef struct PyModuleDef_Slot{
+ int slot;
+ void *value;
+} PyModuleDef_Slot;
+
typedef struct PyModuleDef{
PyModuleDef_Base m_base;
const char* m_name;
const char* m_doc;
Py_ssize_t m_size;
PyMethodDef *m_methods;
- inquiry m_reload;
+ PyModuleDef_Slot* m_slots;
traverseproc m_traverse;
inquiry m_clear;
freefunc m_free;
}PyModuleDef;
+#define Py_mod_create 1
+#define Py_mod_exec 2
+
+#ifndef Py_LIMITED_API
+#define _Py_mod_LAST_SLOT 2
+#endif
#ifdef __cplusplus
}