-
-
Notifications
You must be signed in to change notification settings - Fork 280
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
Adjust is_namespace()
to check ModuleSpec.loader
#2410
Adjust is_namespace()
to check ModuleSpec.loader
#2410
Conversation
95e6e3e
to
e136e55
Compare
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.
@jacobtylerwalls what do you think of this PR? It seems like a correct approach right?
This fixes inference when six.moves is imported. Closes pylint-dev#2409
e136e55
to
a418663
Compare
I pushed force to change the commit message of this "option 1" and also the "option 2" from #2411 this was referencing a wrong issue. |
Yes, this looks promising, thank you! |
This is a draft pull request because I was suggesting this and #2411 at the same time, to discuss two possible approaches. From the feedback, it seems that this option would be better, so I will close the other pull request and mark this one as ready for review. |
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.
@jacobtylerwalls do you want to review this as well?
Yes, on second thought, I would like to take a moment to consider this change in more detail. Reading PEP 451, I'm concerned that |
Thanks, it's good idea to check in more details, I am myself not convinced that this is the best way of detecting namespace packages, the example code you linked and also https://peps.python.org/pep-0451/#namespace-packages describe namespace packages as "a spec with loader set to None". In the case of
From this and from the PEP, it seems the condition should include return (
found_spec is not None
and found_spec.submodule_search_locations is not None
and found_spec.loader is None
and found_spec.origin is None
) but after trying a bit, in practice for namespace packages the loader is not None, it is Would it make sense to adjust the patch with something like this ? ( to be applied on top of this patch ): diff --git a/astroid/interpreter/_import/util.py b/astroid/interpreter/_import/util.py
index cb947800..939f97d5 100644
--- a/astroid/interpreter/_import/util.py
+++ b/astroid/interpreter/_import/util.py
@@ -8,6 +8,11 @@ import pathlib
import sys
from functools import lru_cache
from importlib._bootstrap_external import _NamespacePath
+
+if sys.version_info >= (3, 11):
+ from importlib.machinery import NamespaceLoader
+else:
+ from importlib._bootstrap_external import _NamespaceLoader as NamespaceLoader
from importlib.util import _find_spec_from_path # type: ignore[attr-defined]
from astroid.const import IS_PYPY
@@ -99,6 +104,8 @@ def is_namespace(modname: str) -> bool:
return (
found_spec is not None
- and found_spec.submodule_search_locations
- and found_spec.origin is None
+ and found_spec.submodule_search_locations is not None
+ and (
+ found_spec.loader is None or isinstance(found_spec.loader, NamespaceLoader)
+ )
) I have only tested this patch on python3.9 so far. EDIT: also in the patch I have removed |
I found https://bugs.python.org/issue35673 which mentions a "documentation bug". |
I was following the example here, which gives: if spec.origin is None and spec.submodule_search_locations is not None:
# namespace package |
@perrinjerome Alternatively, does this diff work for you? This looks like a mistake. diff --git a/astroid/interpreter/_import/util.py b/astroid/interpreter/_import/util.py
index a8af9ec6..afead29f 100644
--- a/astroid/interpreter/_import/util.py
+++ b/astroid/interpreter/_import/util.py
@@ -32,7 +32,7 @@ def is_namespace(modname: str) -> bool:
# not, but requires instead that each single parent ('astroid', 'nodes', etc.)
# be specced from left to right.
processed_components = []
- last_submodule_search_locations: _NamespacePath | None = None
+ last_submodule_search_locations = []
for component in modname.split("."):
processed_components.append(component)
working_modname = ".".join(processed_components) |
Never mind, sorry, I ran your test and it doesn't pass with my suggestion. Your latest suggested patch looks good to me--thanks for doing the research. |
Thank you @jacobtylerwalls , I have updated the pull request with the patch we discussed. |
is_namespace()
to check ModuleSpec.loader
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.
Thanks!
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.
Ah, do you have any guidance on the failing pylint run? Did that expose a logic problem?
I think I have fixed the failing pylint test now, by reorganizing imports |
Codecov ReportAll modified and coverable lines are covered by tests β
Additional details and impacted files@@ Coverage Diff @@
## main #2410 +/- ##
==========================================
+ Coverage 92.75% 92.76% +0.01%
==========================================
Files 94 94
Lines 11088 11090 +2
==========================================
+ Hits 10285 10288 +3
+ Misses 803 802 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
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.
@jacobtylerwalls this is good to go right?
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.
Thanks, looks great!
Thank you ! |
Only consider modules with submodule_search_locations namespaces.
Type of Changes
Description
Make
astroid.interpreter._import.util.is_namespace
only consider modules using a loader set toNamespaceLoader
orNone
as namespaces.This fixes a problem that
six.moves
brain was not effective ifsix.moves
was already imported.Closes #2409