-
Notifications
You must be signed in to change notification settings - Fork 784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tracking Issue: Sub-Interpreter Support #3451
Comments
Note that I will update this issue whenever updates, new infos, etc. appear in order to keep everything relatively tidy. |
@Aequitosh, just in case you didn't have seen, David have redirected the Multiple Gill Acquire to here and close the other one to don't have two lines of the same subject, so now we will continue the subject here ;) |
Hi there! For those following this issue, I've got a short update: I'm slowly able to pick up on all this again, now that there are less things going on in my private life. Currently, I'm working on properly drafting up and implementing a prototype of an idea that's been living rent-free in my head the past few weeks - I figured it's finally time I brought it to life in the form of code. More details will follow as soon as I'm more confident with the idea - that is, once I've actually implemented it in prototypical form and seen it in action. See this more as a sign that this issue is still alive; I'm still very eager to work on this, even though I wasn't able to for a while. |
So, I have been working on and off on this. The more I begin to understand how CPython's insides work, the more I realize how complicated this actually is. Nevertheless, I've got a rough plan for removing Per-Module StateFrom what I've been experimenting with, it's probably best to move The absolutely fantastic thing about per-module state is that, according to the CPython docs, it's an arbitrarily-sized block of memory allocated on the Python interpreter's heap that is sub-interpreter safe to access. This makes it the ideal place to store more than just Relocating currently To provide an analogy, this mechanism (or API) would work similar to something like But obviously this goes beyond just storing docstrings - and in my opinion, also beyond just storing static data. A Place For More Than
|
Agreed that per module state is a necessary first step which can have general value beyond subinterpreters. I've actually been playing around with the first step for supporting that, which is changing PyO3 to do something compatible with pep 489. Ideally I can push this soon! |
That's actually fantastic - I've got multi-phase initialization to almost work at the moment; I still have to change a bunch of the proc macro stuff so I can actually attach functions, classes, etc. to my module. It otherwise loads just fine (though I get a double-free when the garbage collector picks it up, woops). Let me know if I can lend a hand or anything! I haven't pushed my stuff yet, but might soon. I'll ping you over at my fork once I do (if that's alright). |
I think part of this would be to have an optional
Thanks! I mostly wrote it to get some experience with it and to get a feel of what it should look like. I'm happy if it does the same for others :) |
Back with an update! I opened up PR #4162, which implements almost fully functional multi-phase module initialization. See the PR for more information. More work will continue off and on in the meantime. Exams are coming up, but I'll try to make some time every now and then. |
Healthcheck: Now that university stuff has cooled down, I can finally dedicate some more time to this again. Just rebased my PR on |
Back with some good news! Multi-phase initialization now works, even for submodules. I've updated PR #4162 correspondingly; it's now an RFC. See the PR's description for more details. It's still a little rough around the edges, but we're getting much closer to merging now, I feel. (Unless something unexpected pops up, that is.) @davidhewitt Kindly pinging you here and asking you to take a look whenever you have time. ;) |
Allow the subinterpreter safeguards to be disabled, so that applications like Ceph's manager can continue to use pyo3 modules without soft crashing. Enabling this feature should be done with caution, as any storage of Py objects in rust statics can lead to undefined behavior. However, not all consumers of pyo3 use global state, and thus a subset of them (such as python-bcrypt) are safe to use in subinterpreter contexts. References: bazaah/aur-ceph#20 References: PyO3#2523 References: pyca/cryptography#9016 References: PyO3#2346 (comment) References: PyO3#2346 (comment) References: PyO3#3451 Signed-off-by: Paul Stemmet <[email protected]>
Allow the subinterpreter safeguards to be disabled, so that applications like Ceph's manager can continue to use pyo3 modules without soft crashing. Enabling this feature should be done with caution, as any storage of Py objects in rust statics can lead to undefined behavior. However, not all consumers of pyo3 use global state, and thus a subset of them (such as python-bcrypt) are safe to use in subinterpreter contexts. References: bazaah/aur-ceph#20 References: PyO3#2523 References: pyca/cryptography#9016 References: PyO3#2346 (comment) References: PyO3#2346 (comment) References: PyO3#3451 Signed-off-by: Paul Stemmet <[email protected]>
Tracks the development and state of supporting sub-interpreters in PyO3.
This issue really only tracks progress, for discussing everything else, feel free to join over here: Aequitosh#1
Summary
As of 13.09.2023
PyO3 currently doesn't support sub-interpreters, which will lead to an
ImportError
being raised if a module using PyO3 is initialized more than once per interpreter process. As stated in #2523, this is necessary in order to prevent soundness holes (as in, prevent things that use PyO3 from randomly breaking, having nasty undefined behaviour, etc.).Even though this prevents soundness holes on the one hand, it can lead to modules / applications using a sub-interpreter model to "break" in certain situations. For examples, see pyca/cryptography#9016 and bazaah/aur-ceph#20.
Implementing sub-interpreter support isn't straightforward and requires quite a substantial redesign of PyO3's API. This issue shall track this redesign and provide as much relevant information as possible for all that wish to contribute.
Goals
Adapted from #576 (comment), as of 13.09.2023.
Mid-Term
static
data from PyO3's implementation, either move things toPyModule_GetState
(preferred) orPyInterpreterState_GetDict
(alternative)unsafe
in order to opt in to sub-interpreter support - it is their responsibility to guarantee to not storePy<T>
in any static data.Long-Term
Possibly remove the need for extension authors to audit their own code once we're confident enough.
Tasks
TBA - might them here (or some other place) once more concrete pieces of work have been identified.
Relevant Issues & Interesting Reads
Listing relevant things here. Some things might already be linked above, but it's nevertheless nice to have everything in one place.
Support sub-interpreters #576
Add support for nogil Python #2885
How can we make Python's C-API more friendly for Rust? #2346 (comment)
cryptography
issue regarding sub-interpreters in PyO3:Different behaviour between 41.0.0, 41.0.1 and 40.0.2 - PyO3 modules may only be initialized once per interpreter process pyca/cryptography#9016
aur-ceph
maintainer's issue regarding Ceph's sub-interpreter model, and why Ceph Dashboard breaks:ceph-mgr/dashboard: python-cryptography PyO3 modules may only be initialized once per interpreter process bazaah/aur-ceph#20
ghostcell
-ish pattern:Support sub-interpreters #576 (comment)
The text was updated successfully, but these errors were encountered: