Closed
Description
The inferred type is wrong here, after the recent typeshed sync:
from typing import TypeVar, Generic, List
T = TypeVar('T')
class C(Generic[T]):
a: List[T]
b: List[str]
def f(self) -> None:
for x, y in zip(self.a, self.b):
reveal_type((x, y)) # Tuple[Tuple[T`1, builtins.str], builtins.str]
The correct type would be Tuple[T, builtins.str]
.
Here's a self-contained example that doesn't depend on typeshed:
from typing import TypeVar, Generic, Iterator, List, Tuple
_T_co = TypeVar("_T_co", covariant=True)
_T1 = TypeVar("_T1")
_T2 = TypeVar("_T2")
S = TypeVar("S")
class Z(Iterator[_T_co]):
def __new__(cls,
__iter1: List[_T1],
__iter2: List[_T2]) -> Z[Tuple[_T1, _T2]]: ...
def __iter__(self: S) -> S: ...
def __next__(self) -> _T_co: ...
T = TypeVar('T')
class C(Generic[T]):
a: List[T]
b: List[str]
def f(self) -> None:
for x, y in Z(self.a, self.b):
reveal_type((x, y)) # Tuple[Tuple[T`1, builtins.str], builtins.str]
The behavior is correct if we avoid using a self type with __iter__
:
def __iter__(self) -> Z[_T_co]: ...
This happens with some frequency in an internal codebase so this seems important to fix.