(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_slotsfield to an array with: - set
def.m_sizeto 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_interpretersas a hypotheticalPy_mod_isolated, wherePy_MOD_PER_INTERPRETER_GIL_SUPPORTEDmeans “isolated” andPy_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTEDmeans “not isolated” ↩︎