Description
Bug description
When specifying on the command line files to check where the name of namespace package shares the name with a regular package in another namespace, the latter is cached in astroid
with the name of the first package. This will cause any usage of the first one to break.
This happens because in two places sys.path is modified (once in place, once when calling astroid
) to include the namespace package that contains the second namespace (I know it's confusing, see the example). But, the correct behaviour is to rely on sys.path
and if the file is importable, not modify sys.path
. This might cache the module with the wrong name (if sys.path
contains, for example, foo
and foo/bar
, the stuff in foo/bar
now is accessible by two names), but this only matters if it's imported, at which point it will be re-imported, with the correct name.
Setup
mkdir -p ns1/ ns2/ns1; touch ns1/m2.py ns2/ns1/__init__.py; echo 'import ns1.m2' > ns1/m1.py
ls -R (for visualising structure)
$ ls -R
ns1 ns2
./ns1:
m1.py m2.py
./ns2:
ns1
./ns2/ns1:
__init__.py
Configuration
[MESSAGES CONTROL]
disable=C0114,W0611
Command used
pylint ns1/m1.py ns2/ns1/__init__.py
Pylint output
************* Module m1
ns1/m1.py:1:0: E0401: Unable to import 'ns1.m2' (import-error)
ns1/m1.py:1:0: E0611: No name 'm2' in module 'ns1' (no-name-in-module)
Expected behavior
This is perfectly valid code, which can be ran from the command line.
My suggested solution, as explained in the description is to check whether the file is importable normally and skip modifying sys.path
. I don't think this would break anything, and it might fix other bugs I cannot imagine right now.
What I did was create a is_importable
function that just calls astroid.modutils.modpath_from_file
and returns False when it gets an import error, True otherwise. Then I skipped adding to sys.path
when the file was directly importable.
I did this in here and here. This broke some tests, but still trying to figure exactly why and whether the tests are wrong or my code breaks some edge case. I'll update the issue once I have an answer on that.
Pylint version
pylint 2.15.0-a0
astroid 2.12.2
Python 3.7.4 (default, Oct 26 2021, 12:29:57)
[Clang 12.0.0 (clang-1200.0.32.29)]
OS / Environment
No response
Additional dependencies
No response