Mypy: Generic Self classmethod fails for generic types

Created on 29 Jun 2017  路  6Comments  路  Source: python/mypy

Repro:

from typing import Generic, TypeVar, Type

_T = TypeVar('_T')
SelfType = TypeVar('SelfType', bound='Friend')

class Friend(Generic[_T]):
    @classmethod
    def make(cls: Type[SelfType]) -> SelfType:  # E: Unsupported type Type["SelfType"]
        return cls()

I suspect the issue is that the type _should_ be:

def make(cls: Type[SelfType[T]]) -> SelfType[T]:
        return cls()

But there is no way to express that that I can tell.

Using an instance method behaves as expected:

from typing import Generic, TypeVar, Type

_T = TypeVar('_T')
SelfType = TypeVar('SelfType', bound='Friend')

class Friend(Generic[_T]):
    other = None  # type: Friend

    def make(self: SelfType) -> SelfType:
        return self

Most helpful comment

I've been sent here by stackoverflow. Issue is still relevant.

All 6 comments

I think this is a duplicate of #3363 and #2354
I think we could leave only one of these three issues open and raise its priority.

@ilevkivskyi I'm fine with that. AFAICT https://github.com/python/mypy/issues/2354 is effectively fixed, the code example below works great:

from typing import Generic, TypeVar, Type

_T = TypeVar('_T')
SelfType = TypeVar('SelfType', bound='Friend')

class Friend(Generic[_T]):
    other = None  # type: Friend

    def make(self: SelfType) -> SelfType:
        return self

class SuperFriend(Generic[_T], Friend[_T]):
    pass


reveal_type(SuperFriend[int]().make())  # E: Revealed type is 'test_generic_self.SuperFriend[builtins.int]'

I'd be fine if classmethods had the same behavior. In fact, @elazarg 's change https://github.com/python/mypy/pull/3633 _mostly_ fixes this issue. The types (as opposed to <nothing>) are correct but declaring the function make still throws an error:

from typing import Generic, TypeVar, Type

_T = TypeVar('_T')
SelfType = TypeVar('SelfType', bound='Friend')

class Friend(Generic[_T]):
    other = None  # type: Friend

    @classmethod
    def make(cls: Type[SelfType]) -> SelfType:  # E: Unsupported type Type["SelfType"]
        return cls()

class SuperFriend(Generic[_T], Friend[_T]):
    pass


reveal_type(SuperFriend[int]().make())  # E:  Revealed type is 'test_generic_self.SuperFriend*[builtins.int*]'

I think the Unsupported type Type["SelfType"] error is a separate issue. It happens even for staticmethod, for which there's no specific check for selftype.

@elazarg got it. If you can land https://github.com/python/mypy/issues/2354 I can debug the Type["SelfType"] issue.

Yeah, it gives the same error when Type[SelfType] is used outside the
Friend class. It's purely because of the use of Type[] with a type
variable that is bound by a generic class.

I've been sent here by stackoverflow. Issue is still relevant.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Stiivi picture Stiivi  路  3Comments

edwardcwang picture edwardcwang  路  3Comments

ericnchen picture ericnchen  路  3Comments

arquolo picture arquolo  路  3Comments

takeda picture takeda  路  3Comments