Repository navigation
gh-158140: Resolve lazily imported sibling submodules independently - #158521
Conversation
662dfea to
56babbc
Compare
|
Sorry fucked up the squash give me sec |
56babbc to
4e83bfa
Compare
|
Is this ready now @pablogsal? |
|
Here's a somewhat surprising change in behaviour: given these two modules: A.py: B.py: Before this PR the use of With this PR, it reports the lazy import in B.py: Swapping the order of the lazy imports used to not have an effect on the traceback, but now it does: the last lazy import wins. I'm not sure if that's fixable, but I think if we need a single location the first lazy import would be a better winner. |
Okay I think I see why we can't do that, either. I think this is fixable later (perhaps by merging lazy objects, storing all the locations and selecting an appropriate one when printing the traceback). Still, it's a little annoying that this used to work as users would expect. |
|
I think there's a similar issue with modules defining |
Yhg1s
left a comment
There was a problem hiding this comment.
All things considered, LGTM. I think the semantic changes are acceptable for 3.15 and we can see if we can improve the error reporting later.
|
🤖 New build scheduled with the buildbot fleet by @hugovk for commit 4e83bfa 🤖 Results will be shown at: https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F158521%2Fmerge If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again. |
|
I think we can fix the A/B case by keeping the declarations keyed by the importing module’s I tried this locally. It’s about 70 lines of C. There’s still ambiguity if two namespaces share the same name, or the same filename for anonymous What do you think, @Yhg1s? |
Yes, I was thinking something similar, but I don't think we should try to fix this for 3.15.0. We can pre-emptively file a bug and fix it later. |
Only the root is now resolved.
|
I merged in the main branch with #157714. |
Co-authored-by: T. Wouters <thomas@python.org> Co-authored-by: Petr Viktorin <encukou@gmail.com>
|
Thanks @pablogsal for the PR, and @Yhg1s for merging it 🌮🎉.. I'm working now to backport this PR to: 3.15. |
|
GH-158613 is a backport of this pull request to the 3.15 branch. |
…dependently (pythonGH-158521) (python#158613) Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com> Co-authored-by: Petr Viktorin <encukou@gmail.com> Co-authored-by: T. Wouters <thomas@python.org> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
A pending child in `lazy_pending_submodules` is keyed only by `(parent, child)`, so a later declaration of the same name by another module replaces the earlier one. Resolving the child then copies the location out of the surviving declaration, so the chained `ImportError` points into the file of a module that merely declared the name. Key the declarations by the declaring module, and select one from the frame's globals at access time, so the child resolves with the declaration in scope where the access is written. A declaration made by another module still names the same child and imports the same thing, so it is still used when there is nothing in scope; its location is then not reported as a frame of the accessing module's traceback. The selection also decides which `__import__` runs, since `_PyLazyImport_LoadChild()` takes `lz_builtins` from the declaration it is given. An access that has a declaration of its own in scope now uses that module's hook instead of the last-registered one's — the case Yhg1s described in the pythongh-158521 review. An access with no declaration in scope is unchanged.
Fixes #158140. With
lazy import pkg.afollowed bylazy import pkg.b, accessingpkg.acurrently importspkg.bfirst. Resolve ordinary dotted imports through the existing pending-child lookup, without publishing placeholders in package dictionaries. Custom namespace builtins and aliased parents retain their existing import behavior.The lazy-import, import, importlib, module, sys and C API suites pass in debug and free-threaded builds. Regression tests cover independent siblings, star imports, declaration cleanup, deleted attributes, import hooks and failed-import retries.
lazy import pkg.a) also imports a later importedpkg.b#158140