Imports that shadow names cannot be made to type-check
Bug Report
--allow-redefinition does not come into effect for imports that shadow a previous import with incompatible types. Even if the previous name is first del'd the error still persists, whether --allow-redefinition is enabled or not.
I found this during work on https://github.com/python/typeshed/pull/11374#issuecomment-1968999481. The upstream library first does a star-import re-exporting hundreds of names, then shadows at least one of them with a wrapper type. The star-import cannot be rewritten due to the sheer number of imported names, but then the name shadowing cannot be prevented.
To Reproduce
Minimized multi-file example
# $ tree .
# .
# ├── bar.py
# ├── foo.py
# ├── __init__.py
# └── py.typed
# foo.py & bar.py
class Repository:
pass
# __init__.py
from .foo import Repository
del Repository # this doesn't work
from .bar import Repository
# Both fails in the same way:
# $ mypy .
# $ mypy --allow-redefinition .
#
# __init__.py:3: error: Incompatible import of "Repository" (imported name has type "type[p.bar.Repository]", local name has type "type[p.foo.Repository]") [assignment]
# Found 1 error in 1 file (checked 3 source files)
One-file example:
- Gist URL: https://gist.github.com/mypy-play/826f927d282282e8f8d51bc4411b4b94
- Playground URL: https://mypy-play.net/?mypy=master&python=3.12&flags=allow-redefinition&gist=826f927d282282e8f8d51bc4411b4b94
from hashlib import md5 as foo
del foo
from sys import path as foo
Expected Behavior
No errors.
Actual Behavior
main.py:3: error: Incompatible import of "foo" (imported name has type "list[str]", local name has type "Callable[[Buffer, DefaultNamedArg(bool, 'usedforsecurity')], _Hash]") [assignment]
Found 1 error in 1 file (checked 1 source file)
Your Environment
- Mypy version used: 1.8.0 & master branch
- Mypy command-line flags: none &
--allow-redefinition - Mypy configuration options from
mypy.ini(and other config files): n/a - Python version used: 3.11 & 3.12
Here's your example modified a bit to use star imports:
from hashlib import *
from sys import path as md5 # error: Incompatible import of "md5" (imported name has type "list[str]", local name has type "Callable[[Buffer, DefaultNamedArg(bool, 'usedforsecurity')], _Hash]") [assignment]
MyPy and Pyright seem to disagree here, with Pyright reflecting the correct runtime type:
from sys import path as md5
from hashlib import *
reveal_type(md5)
Mypy:
main.py:2: error: Incompatible import of "md5" (imported name has type "Callable[[Buffer, DefaultNamedArg(bool, 'usedforsecurity')], _Hash]", local name has type "list[str]") [assignment] main.py:4: note: Revealed type is "builtins.list[builtins.str]" Found 1 error in 1 file (checked 1 source file)
https://mypy-play.net/?mypy=master&python=3.12&flags=allow-redefinition&gist=f2806f836ad111efc7de683277e35d7c
Pyright:
Type of "md5" is "(string: Buffer = b"", *, usedforsecurity: bool = True) -> _Hash"
https://pyright-play.net/?code=GYJw9gtgBAzgnjKBLCAHMIAuVUENMAWUuiEAJgKwCwAUKJFASQQDZIBGyaG2AVLbRABTAG5DcLAPqY4qIQApyFAJS0gA