8000 Generic Self classmethod fails for generic types · Issue #3631 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Generic Self classmethod fails for generic types #3631

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

Closed
rowillia opened this issue Jun 29, 2017 · 6 comments
Closed

Generic Self classmethod fails for generic types #3631

rowillia opened this issue Jun 29, 2017 · 6 comments

Comments

@rowillia
Copy link
Contributor
rowillia commented Jun 29, 2017

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
@ilevkivskyi
Copy link
Member

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.

@rowillia
Copy link
Contributor Author
rowillia commented Jun 29, 2017

@ilevkivskyi I'm fine with that. AFAICT #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 #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*]'

@elazarg
Copy link
Contributor
elazarg commented Jun 30, 2017

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.

@rowillia
Copy link
Contributor Author

@elazarg got it. If you can land #2354 I can debug the Type["SelfType"] issue.

@gvanrossum
Copy link
Member
gvanrossum commented Jun 30, 2017 via email

@bharel
Copy link
bharel commented Jun 29, 2018

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

ilevkivskyi pushed a commit that referenced this issue Aug 2, 2018
Fix #3631 : looks like it was an explicit decision, made before we had self types.

The code modified in this PR was introduced at #1569. There are no tests for the current behavior, and it seems like we actually want to allow it.
4AED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants
0