python / python/mypy

Imports that shadow names cannot be made to type-check

Open
#16,972 2 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

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:

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the issue with init.py, foo.py, and bar.py using the shown mypy commands, including --allow-redefinition. Trace how mypy handles the deleted first import and the incompatible replacement, then add a regression test covering both examples. Done means the imports type-check without errors in both flag configurations.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.