Open arquolo opened 4 years ago
I believe I'm hitting this same bug. Seems like the problem lies with some combination of:
__all__
in one fileMinimal Repro
other_file
:
__all__ = ["name"]
name = "foo"
main_file
:
from .other_file import *
_ = name
This results in the following error message:
main_file.py: E0602: Undefined variable 'name' (undefined-variable)
Output of pylint --version
:
pylint 2.6.0
astroid 2.4.2
Python 3.8.6 (default, Oct 27 2020, 11:18:42)
[Clang 12.0.0 (clang-1200.0.32.27)]
@jamesbraza i'm trying to reproduce your case but i end up with ImportError: attempted relative import with no known parent package
when running python3 main.py
. The file structure is:
tree .
.
├── main_file.py
└── other_file.py
0 directories, 2 files
Hi @hippo91 sorry it looks like I was invoking my minimal repro differently. The error you're getting lies in the concepts from this stack overflow question: Relative imports in Python 3.
There are multiple options at invocations for directly with python3
, including:
.
from from .other_file import *
in main_file.py
and use python3 main_file.py
undef_var_bug
and change import
to include parent folderundef_var_bug
├── main_file.py
└── other_file.py
Update import in from undef_var_bug.other_file import *
, and invoke via python3 -m undef_var_bug.main_file
.
Let me know if neither of those work for you.
@jamesbraza , i tested with the first solution. So i have the following code structure:
tree bug_pylint_3298
bug_pylint_3298
├── main_file.py
└── other_file
with:
cat bug_pylint_3298/main_file.py
from other_file import *
_ = name
and
cat bug_pylint_3298/other_file.py
__all__ = ["name"]
name = "foo"
Then linting is ok:
pylint bug_pylint_3298
************* Module bug_pylint_3298.main_file
bug_pylint_3298/main_file.py:1:0: C0114: Missing module docstring (missing-module-docstring)
bug_pylint_3298/main_file.py:1:0: W0401: Wildcard import other_file (wildcard-import)
************* Module bug_pylint_3298.other_file
bug_pylint_3298/other_file.py:1:0: C0114: Missing module docstring (missing-module-docstring)
bug_pylint_3298/other_file.py:3:0: C0103: Constant name "name" doesn't conform to UPPER_CASE naming style (invalid-name)
pylint --version
pylint 2.6.1-dev1
astroid 2.5.0
Python 3.7.9 (default, Nov 26 2020, 08:29:18)
[GCC 8.3.0]
The false positive undefined-variable
message emission doesn't occur. Do you agree?
@hippo91
No, undefined-variable
message does occur, you invoke it wrong. I have updated issue
@hippo91 so I copied what you'd set up, and I figured out the problem, I don't believe your code actually runs. I know because when I ran it via python -m bug_pylint_3298.main_file
, the result was: ModuleNotFoundError: No module named 'other_file'
Your main_file.py
begins with from other_file
:
from other_file import *
However, it should be:
from bug_pylint_3298.other_file import *
And now the module executes as intended. And then when you invoke pylint
, the bug surfaces:
(venv) ➜ bananas_dir pylint bug_pylint_3298
************* Module bug_pylint_3298.main_file
bug_pylint_3298/main_file.py:1:0: C0114: Missing module docstring (missing-module-docstring)
bug_pylint_3298/main_file.py:1:0: E0401: Unable to import 'bug_pylint_3298.other_file' (import-error)
bug_pylint_3298/main_file.py:1:0: W0401: Wildcard import bug_pylint_3298.other_file (wildcard-import)
bug_pylint_3298/main_file.py:3:4: E0602: Undefined variable 'name' (undefined-variable)
************* Module bug_pylint_3298.other_file
bug_pylint_3298/other_file.py:1:0: C0114: Missing module docstring (missing-module-docstring)
bug_pylint_3298/other_file.py:3:0: C0103: Constant name "name" doesn't conform to UPPER_CASE naming style (invalid-name)
To fix it in this case, one can add an __init__.py
to the bug_pylint_3298
directory, and it seems the error disappears.
(venv) ➜ bananas_dir pylint bug_pylint_3298
************* Module bug_pylint_3298.main_file
bug_pylint_3298/main_file.py:1:0: C0114: Missing module docstring (missing-module-docstring)
bug_pylint_3298/main_file.py:1:0: W0401: Wildcard import bug_pylint_3298.other_file (wildcard-import)
************* Module bug_pylint_3298.other_file
bug_pylint_3298/other_file.py:1:0: C0114: Missing module docstring (missing-module-docstring)
bug_pylint_3298/other_file.py:3:0: C0103: Constant name "name" doesn't conform to UPPER_CASE naming style (invalid-name)
Seems like pylint
:
import-error
undefined-variable
, since it can't seem to parse the wildcard import (hence the preceding import-error
)However, @arquolo seems to have changed the issue to be from E0602 (undefined-variable)
to E1101 (no-member)
w.r.t. module.__all__
, which now makes my contributions here being sort of off-topic.
@arquolo I think your problem may be in the fact that python -c
is different from just invoking pylint
.
Invoking via python -c
runs the input as if it's a __main__
, which is why this works. However, if you were to try and invoke in a plain way, you can see Python can't actually run:
(venv) ➜ bananas_dir tree bug
bug
├── __init__.py
└── module.py
(venv) ➜ bananas_dir python -m bug
/path/to/bin/python: No module named bug.__main__; 'bug' is a package and cannot be directly executed
This may be why pylint
can't properly parse the wildcard import... somewhere behind the scenes the real problem may be that the module can't be run. Just my guess, but I am not sure.
@jamesbraza
I have updated issue, and yet it's still E0602 (it was 2 am here, I misread the log).
It doesn't depend whether module is imported in python -c
, or in a plain way in python script, it still works.
I'm not trying to run a package, but import it.
Problem is not with star import, but with star import from subpackage, what imports subpackage too, and Pylint fails with last.
@arquolo and @jamesbraza thanks for your remarks. I'm now able to reproduce the bug.
Here is attached a reproducer. I can confirm that adding an empty __init__.py
file makes the bug disappear. That's why this issue may be linked to #3944.
bug_pylint_3298.tar.gz
I've been running into the same problem. It is as simple as
from .x import y
del x # undefined-error!
in any file inside a package. Pylint just needs to do what Python does, which is to add an implicit import x
.
Is this similar to
src/matplotlib-stubs/__init__.pyi:37:17: E0602: Undefined variable 'PathLike' (undefined-variable)
Given:
with
bug/__init__.py
:and
bug/module.py
:and
run_bug.py
:code works:
and this also works:
and bug is here:
Problem is that when
*
is imported frombug.module
,module
becomes imported tobug
, but PyLint thinks that it doesn't. All I wanted is to delegate filling of__all__
to submodules, like in asyncio. Explanation is here.