Skip to content

Invalid type inference for zip in a generic class #12588

Closed
@JukkaL

Description

@JukkaL

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-self-typesTypes for self

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions