Description
Bug description
If you shadow a base module with an alias, and then call a method named format()
on the alias in the code your are linting, checkers/variables.py:_infer_name_module
yields the wrong module, causing checkers/variables.py:_check_module_attrs
to fail on line 3120 (in pylint 3.3.3), and return an invalid no-name-in-module
on line 3130.
As a simple example, let's say you have the following code structure:
- main.py
- my_module
- __init__.py
- utils.py
And utils.py has the following code:
def format():
pass
def other_method():
pass
If in main.py
you have the following code:
import my_module.utils as my_module
my_module.format()
Then pylint will fail with main.py:1:0: E0611: No name 'utils' in module 'my_module.utils' (no-name-in-module)
. This is obviously invalid, because we're not trying to import utils
from my_module.utils
in the code as the message suggests, but _infer_name_module
is returning the module my_method.utils
and then _check_module_attrs
is trying to access module.getattr(name)[0]
where name is utils
, causing this error.
Disclaimer: I know that import my_module.utils as my_module
isn't good practice, but it is valid Python, and we have a legacy usecase for it that we unfortunately can't drop.
The wild thing to me is that if main.py
instead just does the import, _infer_name_module
correctly returns the my_module
module, and there is no error. For example:
import my_module.utils as my_module
Even more wild, if you call any other method name on the alias in main.py (at least any that I have tried), _infer_name_module
also correctly returns the my_module
module, and there is no error. For example:
import my_module.utils as my_module
my_module.other_method()
Less surprising, is that if you don't shadow the base module with the alias, but still call format()
, you also don't get an error:
import my_module.utils as different_alias
different_alias.format()
It is something specific about the combination of shadowing the base module with an alias and calling a method called .format()
on that alias that causes _infer_name_module
to do the inference incorrectly, resulting in this error.
Configuration
Command used
pylint main.py --disable=missing-docstring
Pylint output
************* Module main
main.py:1:0: E0611: No name 'utils' in module 'my_module.utils' (no-name-in-module)
Expected behavior
No failures
Pylint version
pylint 3.3.3
astroid 3.3.8
Python 3.12.4 (main, Aug 28 2024, 13:49:33) [Clang 15.0.0 (clang-1500.3.9.4)]
I also tried older versions, and got the same behavior, for example:
pylint 2.15.0
astroid 2.13.5
Python 3.12.4 (main, Aug 28 2024, 13:49:33) [Clang 15.0.0 (clang-1500.3.9.4)]
OS / Environment
macOS 15.1.1, ubuntu 20.04
Additional dependencies
None