Description
PEP 484 has: "A type variable used in a method of a generic class that coincides with one of the variables that parameterize this class is always bound to that variable." The example there has:
T = TypeVar('T')
class MyClass(Generic[T]):
def meth_1(self, x: T) -> T: ...
This should mean that T occurs bound in the signature of meth_1 (it is bound to the type parameter of the generic class MyClass).
The signature of MyClass[int].meth_1 should be (self:MyClass[int],x:int)->int
. This is gotten from the signature of the function in the generic class with the type argument int substituted for occurrences of the type parameter T.
The signature of MyClass.meth_1 should be (self:MyClass[Any],x:Any)->Any
. The generic class is implicitly instantiated to Any. Further, we must substitute something for the occurrences of the type parameter in the signature (the type parameter can't become a free occurrence just by looking at it from outside the class).
Mypy seems to do something else. The type of MyClass[int].meth_1 is revealed as:
def (self: test.MyClass[T`1], x: T`1) -> T`1
Instead of substituting int for T it has used some other type (maybe a free type variable?). If we try to apply it to an instance of MyClass[int] and an int, we get that the type of the application is T`1 whatever that is, and we get errors:
error: Argument 1 has incompatible type "MyClass[int]"; expected "MyClass[T]"
error: Argument 2 has incompatible type "int"; expected "T"
The type of MyClass.meth_1 is revealed as:
def [T] (self: test.MyClass[T`1], x: T`1) -> T`1
This looks like it might be a generic function, but MyClass.meth_1 should not be generic (it has no free type variables). There is actually no occurrence of the type parameter T in the signature, it seems to have been instantiated to T`1 whatever that is (unless T`1 is another spelling of T).
This function does behave as if it were generic, actually. We can apply it to an instance of MyClass[int] and an int and the type of the application is int. And it's apparently not an instantiation to Any because if we try to apply it to an instance of MyClass[int] and a str it is a type error "Cannot infer function argument".
What I think is happening is that mypy is treating functions in generic classes as themselves generic functions parameterized over the class's type parameters. This seems wrong or else I've completely misunderstood PEP 484.