Thanks for the explanation. @steve.dower covered some of what I would have said. (For more discussion about the free-threading build and PyUnstable_Module_SetGIL()
, check out my other thread: https://discuss.python.org/t/concerns-about-pyunstable-module-setgil/89374).
I do want to reiterate something I pointed out in an earlier comment, that implementing multi-phase init is not the same thing as implementing module isolation. Your explanation implies to me that you understand the two to be the same, which seems to be a fairly common misunderstanding. You can actually implement multi-phase init without the rest of module isolation. (See my earlier post in this thread and my post in the other thread for more info.)
Regarding subinterpreters, what you’ve written is very helpful. Thanks for taking the time to write it up. There isn’t a problem with saying “this module does not support use in multiple interpreters.” Multi-phase init supports that. That said, I’m sure the Python community will ultimately dictate how much users expect extension modules to support use in multiple interpreters.
Also note that we are seriously looking into eventually adjusting the C-API to make the CPython runtime context explicit, instead of relying on a thread-local variable (accessed through PyThreadState_Get()
). This would mean nearly all functions would add a context argument (like HPy has), which would effectively be equivalent to an opaque PyThreadState
. While this might not change the constraints on nanobind state management much (I’m not sufficiently familiar with nanobind to say), I expect such a change would have some impact on those constraints.