Skip to content

Commit 46be0f7

Browse files
committed
improve is_namespace check
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From #1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. But if you have imported it as `celery.result`, `sys.modules["celery"].__spec__` is going to be `None`, and hence the function will return True, and but below where we try to load get `submodule_path`/`__path__` for `celery.result` will fail as it is not a package. See https://github.com/PyCQA/astroid/blob/056d8e5fab7a167f73115d524ab92170b3ed5f9f/astroid/interpreter/_import/spec.py#L205-L207 --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `find_spec("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. I still think there's a bug for the `ExplicitNamespacePackageFinder.find_module` for namespace packages, since `modname` might be `namespace.package.module` but since `is_namespace` package goes through components, the successive `sys.modules[modname].__path__` may raise error, since modname could be not a package in a namespaced package. But I am not quite sure about that. Fixes pylint-dev/pylint#7488.
1 parent 849d043 commit 46be0f7

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

astroid/interpreter/_import/util.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ def is_namespace(modname: str) -> bool:
5252
# Check first fragment of modname, e.g. "astroid", not "astroid.interpreter"
5353
# because of cffi's behavior
5454
# See: https://github.com/PyCQA/astroid/issues/1776
55+
mod = sys.modules[processed_components[0]]
5556
return (
56-
sys.modules[processed_components[0]].__spec__ is None
57+
mod.__spec__ is None
58+
and getattr(mod, "__file__", None) is None
59+
and hasattr(mod, "__path__")
5760
and not IS_PYPY
5861
)
5962
except KeyError:

0 commit comments

Comments
 (0)