MyPy reports errors when performing nested element access using a ``TypeVar``-parameterized generic type
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
Type variables and generics enable propagating finer-grained type information through objects like containers. However, it seems that MyPy has issues when this design pattern is used in a nested manner:
To Reproduce
import typing
T = typing.TypeVar("T")
class Container(typing.Generic[T]):
def __init__(self, value : T) -> None:
self.value = value
class A(Container[int]):
pass
class B(Container[A]):
pass
def get(x: Container[T]) -> T:
return x.value
a = B(A(5))
reveal_type(a)
b = get(a)
reveal_type(b)
c1 = get(b)
reveal_type(c1)
# This is expected to match 'c1'
c2 = get(get(a))
reveal_type(c2)
MyPy-Play link: https://gist.github.com/mypy-play/40d62fe7a0fc28bf68bd9d156ba77c5b
a.py:20: note: Revealed type is "a.B"
a.py:23: note: Revealed type is "a.A"
a.py:26: note: Revealed type is "builtins.int"
a.py:30: note: Revealed type is "builtins.int"
Reference (PyRight):
/Users/wjakob/drjit-nanobind/a.py
/Users/wjakob/drjit-nanobind/a.py:20:13 - information: Type of "a" is "B"
/Users/wjakob/drjit-nanobind/a.py:23:13 - information: Type of "b" is "A"
/Users/wjakob/drjit-nanobind/a.py:26:13 - information: Type of "c1" is "int"
/Users/wjakob/drjit-nanobind/a.py:30:13 - information: Type of "c2" is "int"
Actual Behavior
a.py:20: note: Revealed type is "a.B"
a.py:23: note: Revealed type is "a.A"
a.py:26: note: Revealed type is "builtins.int"
a.py:29: error: Argument 1 to "get" has incompatible type "B"; expected "Container[Container[int]]" [arg-type]
a.py:30: note: Revealed type is "builtins.int"
Found 1 error in 1 file (checked 1 source file)
Your Environment
Python 3.12.2, MyPy 1.8.0
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
Start with the a.py reproduction from the issue, using Python 3.12.2 and MyPy 1.8.0, and compare it with the linked MyPy-Play example. Investigate nested TypeVar inference for get(get(a)). Done means the nested call produces no incompatible-argument error and c2 is revealed as builtins.int, matching c1.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100