Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect inference of type parameter for a generic container #3183

Open
pkch opened this issue Apr 18, 2017 · 2 comments
Open

Incorrect inference of type parameter for a generic container #3183

pkch opened this issue Apr 18, 2017 · 2 comments
Labels
bug mypy got something wrong

Comments

@pkch
Copy link
Contributor

pkch commented Apr 18, 2017

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.

@gvanrossum
Copy link
Member

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]?

@pkch
Copy link
Contributor Author

pkch commented Apr 18, 2017

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.

@AlexWaygood AlexWaygood added the bug mypy got something wrong label Mar 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

3 participants