(This is essentially a repost of a comment on another thread. I think it’s worth repeating here.)
I want to elaborate on how implementing multi-phase init is fairly trivial [1]:
- move the content[2] of the existing module init function to a new “module exec” function
- set the module def’s
m_slots
field to an array with: - set
def.m_size
to 0 (if negative) - update the module init function to only
return PyModuleDef_Init(moddef);
(Also see Module Objects — Python 3.13.3 documentation and https://docs.python.org/3/howto/isolating-extensions.html.)
There’s no need to do any of the isolation stuff (heap types, module state, etc.) immediately.
FYI, at that point the only extra step to run without the GIL on a free-threading build would be to add the Py_mod_gil
slot[^7], set to Py_MOD_GIL_NOT_USED
. (The default is Py_MOD_GIL_USED
.)
my original outline of the steps: https://github.com/python/cpython/pull/116882#discussion_r1586449047 ↩︎
You’ll drop the call to create the module object. ↩︎
the default is
Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED
↩︎think of
Py_mod_multiple_interpreters
as a hypotheticalPy_mod_isolated
, wherePy_MOD_PER_INTERPRETER_GIL_SUPPORTED
means “isolated” andPy_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED
means “not isolated” ↩︎