spurious used-before-def on admittedly odd wildcard import
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
When using wildcard imports and modifying the import module-level variables, mypy will detect a undef-before-use of imported module-level variables. This is an admittedly weird bit of code, but crops up, for example, in some kinds of Django settings.py refactorings people do.
To Reproduce
This bug unfortunately requires two files to reproduce, so I have to inline them here.
Executing last.py will get you correct output, but mypy will claim there's a undef-before-use.
# first.py
A_VALUE: str = "in first"
# last.py
from first import *
# from first import A_VALUE
A_VALUE += " in last" # comment either this, or the next line, or uncomment the import above for the mypy check to pass
A_VALUE = "in last again " + A_VALUE
if __name__ == "__main__":
print(A_VALUE)
Expected Behavior
The expected behavior would be a successful pass, I believe.
Actual Behavior
Running PYTHONPATH=. mypy last.py will get you:
last.py:3: error: Name "A_VALUE" is used before definition [used-before-def]
Found 1 error in 1 file (checked 1 source file)
For context, running PYTHONPATH=. python3 last.py will show the expected output of in last again in first in last.
Interestingly, both A_VALUE updates in last.py are necessary for mypy to call out a used-before-def. And if you explicitly import the module-level variable, mypy passes successfully, too. We've seen this behavior with a .index and a += method call on a List before a =, so we don't believe it's something specific to str or +=.
Your Environment
- Mypy version used: 1.0.0
- Mypy command-line flags: N/A
- Mypy configuration options from
mypy.ini(and other config files): N/A - Python version used: 3.10.9 and 3.8.14
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the report with first.py and last.py using PYTHONPATH=. mypy last.py, then compare the wildcard import with the explicit import and with either update removed. Trace how wildcard-import names reach the used-before-def check; done means the two-file example passes without suppressing the diagnostic while preserving the existing behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100