You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
from typing import *
T = TypeVar('T', bound='A')
class X: ...
class Y(X): ...
class A(Iterable[X]):
def __iter__(self) -> Iterator[X]: ...
class B(A, Iterable[Y]):
def __iter__(self) -> Iterator[Y]: ...
b = B()
for x in b:
reveal_type(x) # 'Y*'
y = list(b)
reveal_type(y) # 'builtins.list[X*]'
The first reveal_type is correct.
The second is wrong: it should be builtins.list[Y*]. Somehow the presence of A in the bases of B causes this mistake.
In addition, even a workaround doesn't work:
z = List[Y](b) # Argument 1 to "list" has incompatible type "B"; expected Iterable[Y]
reveal_type(z) # 'builtins.list[Y*]'
The revealed type is now correct, but the constructor doesn't pass the type check.
The text was updated successfully, but these errors were encountered:
Yeah, for and list() are treated completely differently -- for is special-cased in mypy, essentially using structural typing, which finds the __iter__ defined in B, while list() uses nominal typing (until PEP 544 is accepted and implemented). I'm guessing that in the second case the MRO search causes mypy to misfire -- it's probably something like B, A, Iterable[X], Iterable[Y], object. Maybe the MRO calculation needs to be revised to correctly order the two Iterable[] base classes, or merge them into just Iterable[Y]?
The fix seems to be super simple. Unfortunately, I have trouble tweaking the test fixtures to accept the code that runs in production. Once I succeed, I'll submit a PR.
The first
reveal_type
is correct.The second is wrong: it should be
builtins.list[Y*]
. Somehow the presence ofA
in the bases ofB
causes this mistake.In addition, even a workaround doesn't work:
The revealed type is now correct, but the constructor doesn't pass the type check.
The text was updated successfully, but these errors were encountered: