(This is a response to a comment in a separate thread discussing a soft deprecation of support for single-phase init extension modules, which I don’t want to get distracted by free-threading stuff. )
PyUnstable_Module_SetGIL()
was added unofficially. The only discussion about it was my objection to it [1] a year ago in the PR that added it (with an ensuing temporary compromise). It was added strictly only so folks can try out the free-threading build sooner (and originally named PyModule_ExperimentalSetGIL()
to reflect this).
From an official standpoint, PEP 703 only proposes support for multi-phase init modules (via Py_mod_gil). Thus, PyUnstable_Module_SetGIL()
(or PyModule_SetGIL()
) should not be treated as official until it is added to PEP 703 and gets appropriate attention and discussion. It should not be a recommended tool until then, outside of experimentation. (That was kind of the point of the original PyModule_ExperimentalSetGIL()
name.)
My original concerns remain. Furthermore, it feels like they were mostly ignored when I first brought them up and that they are still considered inconvenient.
---------------------
To be clear, my main concern is that Py*Module_SetGIL()
is both unnecessary and reinforces use of an outdated, legacy feature (single-phase init) which we would like to eliminate. My comments in the original PR thread cover things fairly well. (See gh-116322: Add Py_mod_gil module slot by swtaarrs · Pull Request #116882 · python/cpython · GitHub)
IMHO, Py*Module_SetGIL()
should be treated as strictly temporary and eventually removed. It should not be advertised as part of the long-term solution.
Clearly users are under the impression that it is.
That’s exactly what I expected would happen and why I pushed back on the original addition. At the time it was added, the argument for Py*Module_SetGIL()
was that the multi-phase init requirement was getting in the way of people trying out the free-threading build and thus providing feedback.
I definitely understand and relate to such barriers to adoption all too well. Furthermore, I was on board with adding PyModule_ExperimentalSetGIL()
as a temporary workaround. However, it’s getting entrenched. [2] Renaming it to PyUnstable_Module_SetGIL()
made it worse. Just because we’re worried about barriers to adoption, however minor, it doesn’t mean we have to cut corners. That’s not how we operate. [3] The free-threading project should not be given special treatment. The zen of Python is quite appropriate here.
So what do I suggest is the long-term solution? It’s the already proposed (and implemented) multi-phase init module slot, Py_mod_gil. Extension maintainers can use it right now. I’m not recommending some new invention.
You might say “but then users have to implement multi-phase init!” For one thing, that’s a good thing. For another, that concern represents a misunderstanding (which we’re discussing in another thread), where people have conflated multi-phase init with isolation (which involves switching to module state and heap types). [4]
Just implementing multi-phase init is fairly trivial, as I noted a year ago. I’ll post an elaborating comment in a moment.
With all that in mind, I don’t thing Py*Module_SetGIL()
is needed. I do think it should be removed.
https://github.com/python/cpython/pull/116882#discussion_r1575006053 ↩︎
With the status quo, eventually we’ll end up keeping
Py*Module_SetGIL()
, without a deliberate public decision to do so, because “people are used to it” and we don’t want to inconvenience them. That’s a mistake we can avoid. ↩︎Otherwise I’d have done a number of things quite differently with my own projects. ↩︎
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. That said, switching to multi-phase init remains trivial. ↩︎