Skip to content

Incorrect type inference when using generics of "union" TypeVars #7913

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

Open
wadetregaskis-linkedin opened this issue Nov 9, 2019 · 6 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-type-variables

Comments

@wadetregaskis-linkedin
Copy link

wadetregaskis-linkedin commented Nov 9, 2019

from typing import MutableSet, Sequence, TypeVar

T = TypeVar('T', str, Sequence[str])

class CustomSet(MutableSet[T]):
    def add(self, value: T) -> None:
        pass

foo = CustomSet()
foo.add(('a', 'b'))

mypy 0.740 says: error: Argument 1 to "add" of "CustomSet" has incompatible type "Tuple[str, str]"; expected "str"

There's seemingly nothing I can do to get mypy to handle this pattern correctly. If I try explicitly specifying the type of foo, it just complains that the assignment to it is incompatible.

@wadetregaskis-linkedin
Copy link
Author

And to be clear, this is irrespective of whether T includes Sequence[str] as in my real code from which this case is simplified, or an extremely literal Tuple[str, str] - it appears that no matter what, mypy stubbornly assumes T is always str. It's not related to the order in the TypeVar either; moving str to the end doesn't influence mypy.

@wadetregaskis-linkedin
Copy link
Author

But changing str to int in the TypeVar does make mypy now stubbornly assume foo takes ints. For some reason mypy is picking the 'simplest' type in the TypeVar, to fixate on.

@jonathanslenders
Copy link

I think I have the same issue here:

import asyncio

async def f() -> None:
    future: asyncio.Future[None] = asyncio.Future()

    # error: Argument 1 to "gather" has incompatible type "Future[None]";
    #     expected "Union[Future[<nothing>], Generator[Any, None, <nothing>], Awaitable[<nothing>]]"
    await asyncio.gather(future)

@JelleZijlstra
Copy link
Member

@jonathanslenders that sounds like #8051.

@JukkaL
Copy link
Collaborator

JukkaL commented Dec 3, 2019

The inferred type for foo is incorrect (CustomSet[str]). Mypy should require a type annotation here.

You can work around the issue by adding an explicit type annotation:

...
foo: CustomSet[Sequence[str]] = CustomSet()
foo.add(('a', 'b'))

@JukkaL JukkaL added bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-type-variables labels Dec 3, 2019
@MarioIshac
Copy link

MarioIshac commented Aug 29, 2020

I may have ran into same issue here:

from typing import Union, TypeVar, Sequence

T = TypeVar("T", bound=Union[int, str])

def a(t: Sequence[T]):
    return t

a([1, "a"])

results in:

Value of type variable "T" of "a" cannot be "object"

but

b: Sequence[Union[int, str]] = [1, "a"]
a(b)

works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-type-variables
Projects
None yet
Development

No branches or pull requests

5 participants