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

Generic[T] erroring when T = TypeVar("T", A, B) and passed subclass of A #8724

Closed
jamesbraza opened this issue Apr 25, 2020 · 2 comments
Closed
Labels

Comments

@jamesbraza
Copy link
Contributor

I have a class that inherits from Generic[T], where is T = TypeVar("T", A, B).

When feeding in A or B, mypy raises no errors. However, when feeding in a subclass of A (called ASub), mypy errors.

In my opinion, mypy should not error when feeding in a subclass. I believe this is a bug.

Here is sample code necessary to reproduce what I am seeing.

from typing import Union, TypeVar, Generic

class A:
    pass

class ASub(A):
    pass

class B:
    pass

# Case 1... Success: no issues found
# T = TypeVar("T", bound=Union[A, B])

# Case 2... error: Value of type variable "T" of "SomeGeneric" cannot be "ASub"
T = TypeVar("T", A, B)

class SomeGeneric(Generic[T]):
    pass

class SomeGenericASub(SomeGeneric[ASub]):
    pass

I included the Union case as a comment to highlight that for some reason, Union doesn't raise an error. However, I don't see why it should not error, when using just A, B does error

I am invoking mypy from the command line with no flags. Here are my versions:

python==3.6.5
mypy==0.770

Aside

I encountered this issue, and then discovered the "minimal repro" was already asked in Stack Overflow here. However, the answer provided did not actually solve the problem, so I think this is a bug in mypy.

I apologize in advance if this is a duplicate issue.

@msullivan
Copy link
Collaborator

Yeah I think this seems like a bug. Probably not too hard to fix if you want to submit a PR. Looks like check_type_var_values in semanal_typeargs.py is the culprit.

This sort of constrained type variable is usually best avoided, though, except when it is absolutely necessary.

@JukkaL
Copy link
Collaborator

JukkaL commented May 1, 2020

This is mypy working as intended. Value restriction only allows those specific types. If you want to allow subtypes, use a bound.

Here's a motivating example:

from typing import TypeVar

T = TypeVar("T", int, str)

def f(x: T) -> T:
    if isinstance(x, int):
        return 0
    else:
        return "x"

class mystr(str):
    def f(self): pass

f(mystr()).f()  # Not safe

@JukkaL JukkaL closed this as completed May 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants