Proposed new feature or change:
This is intended to be a tracking issue for a series of PRs I will shortly submit.
Multi-phase initialisation was introduced in PEP 489 for Python 3.5. It replaces the previous 'single-phase' mechanism by splitting the module creation process into creation and execution phases. Quoting from the documentation:
Extension modules created this way behave more like Python modules: the initialization is split between the creation phase, when the module object is created, and the execution phase, when it is populated. The distinction is similar to the __new__() and __init__() methods of classes.
This is also the stable mechanism to declare compatibility with both free-threading and subinterpreters (though note that this PR does not attempt to add support for subinterpreters).
A common point of confusion/conflation is multi-phase initialisation and module isolation. As noted on the Python Discourse forum, "Implementing extension module isolation is a very good thing, but if a module uses static types or (C) global variables then the effort to isolate becomes non-trivial.". This issue only seeks to implement multi-phase initialisation, generally following the guide that Eric set out in that thread:
- move the content of the module’s init function to a corresponding “module exec” function (dropping the call to create the module object)
- set the module def’s
m_slots field to an array with:
- a
Py_mod_exec slot, set to the new module exec function
- a
Py_mod_multiple_interpreters slot, set to Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED
- to try free-threading, a
Py_mod_gil slot, set to Py_MOD_GIL_NOT_USED
- set
def.m_size to 0 (if negative)
- update the module init function to only
return PyModuleDef_Init(def); for the corresponding module def
cc @ngoldbaum
xref:
A
PRs:
Note: substantial discussion on initial multi-phase changes is contained in GH-29030 ('Convert umath_linalg to multi-phase init').
A
Proposed new feature or change:
This is intended to be a tracking issue for a series of PRs I will shortly submit.
Multi-phase initialisation was introduced in PEP 489 for Python 3.5. It replaces the previous 'single-phase' mechanism by splitting the module creation process into creation and execution phases. Quoting from the documentation:
This is also the stable mechanism to declare compatibility with both free-threading and subinterpreters (though note that this PR does not attempt to add support for subinterpreters).
A common point of confusion/conflation is multi-phase initialisation and module isolation. As noted on the Python Discourse forum, "Implementing extension module isolation is a very good thing, but if a module uses static types or (C) global variables then the effort to isolate becomes non-trivial.". This issue only seeks to implement multi-phase initialisation, generally following the guide that Eric set out in that thread:
m_slotsfield to an array with:Py_mod_execslot, set to the new module exec functionPy_mod_multiple_interpretersslot, set toPy_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTEDPy_mod_gilslot, set toPy_MOD_GIL_NOT_USEDdef.m_sizeto 0 (if negative)return PyModuleDef_Init(def);for the corresponding module defcc @ngoldbaum
xref:
A
PRs:
Note: substantial discussion on initial multi-phase changes is contained in GH-29030 ('Convert umath_linalg to multi-phase init').
A