-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
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
gh-123880: Allow recursive import of single-phase-init modules #123950
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the fix, confirmed it on the end-to-end mypyc repro as well. I was wondering if we could get away with just removing the assert like this :-) I noticed two trivial typos in comments
Co-authored-by: Shantanu <[email protected]>
Lib/test/test_import/__init__.py
Outdated
loader = importlib.machinery.ExtensionFileLoader(name, filename) | ||
spec = importlib.util.spec_from_file_location(name, filename, | ||
loader=loader) | ||
mod = importlib._bootstrap._load(spec) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if I love using this API for the test since it's somewhat of a hack to start, but I also understand not wanting to paste in 2 more lines of boilerplate to get the module created and set sys.modules
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was done elsewhere in the file too; I merged the usage into a common helper. If it breaks, there's now just one place to change.
(We never got around to adding proper public API for multiple modules in one shared library, but then, it's really only useful for testing import mechanism...)
In this case I slightly prefer not to touch sys.modules
here -- the “inner” import should do that.
Co-authored-by: Brett Cannon <[email protected]>
!buildbot iOS |
!buildbot iOS |
Thanks @encukou for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13. |
…ythonGH-123950) (cherry picked from commit aee219f) Co-authored-by: Petr Viktorin <[email protected]> Co-authored-by: Shantanu <[email protected]> Co-authored-by: Brett Cannon <[email protected]>
GH-124273 is a backport of this pull request to the 3.13 branch. |
…ythonGH-123950) Co-authored-by: Shantanu <[email protected]> Co-authored-by: Brett Cannon <[email protected]>
…ythonGH-123950) Co-authored-by: Shantanu <[email protected]> Co-authored-by: Brett Cannon <[email protected]>
…GH-123950) (#124273) gh-123880: Allow recursive import of single-phase-init modules (GH-123950) (cherry picked from commit aee219f) Co-authored-by: Petr Viktorin <[email protected]> Co-authored-by: Shantanu <[email protected]> Co-authored-by: Brett Cannon <[email protected]>
Single-phase modules can imported recursively, if they take care of returning the partially initialized module in such cases.
Concretely,
mypyc
emits a globalstatic PyObject* module = NULL;
set right afterPyModule_Create
and checked+returned right before it. This is of course utterly incompatible with multiple interpreters and withPy_Finalize
/Py_Initialize
“power cycles”, but, it works for their use cases.Unless I'm missing something, the assert that
mypyc
is running into can be removed, and the cache value reused. Deallocation of the cache values is done in a few places, but none of them can reasonably happen witin a (recursive) import.(Here I beg people to not try destroying pre-existing interpreters from within a recursive single-phase
PyInit_*
function -- please! single-phase init is a bowl of backcompat spaghetti; even after Eric's untangling, it can only take so much. See severalXXX
notes elsewhere inimport.c
.)I'm sending this draft early, I still have to check more of the code and write a regression test.