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

Seemingly valid classmethod in subclass of generic generates incompatible return type error #7401

Closed
erickpeirson opened this issue Aug 28, 2019 · 2 comments

Comments

@erickpeirson
Copy link

Are you reporting a bug, or opening a feature request?

Encountered an unexpected behavior (bug?) when working with classmethods on generics. It is also possible that I have misunderstood how this is supposed to work.

Please insert below the code you are checking with mypy,

Here is a minimal example:

T = TypeVar('T')
Self = TypeVar('Self', bound='Foo')

class Foo(Generic[T]):
    a: T

    def __init__(self, a: T) -> None:
        self.a = a

    @classmethod
    def oof(cls: Type[Self], a: T) -> Self:
        return cls(a)


class Baz(Foo[str]):
    @classmethod
    def oof(cls, a: str) -> 'Baz':  # error: Return type "Baz" of "oof" incompatible with return type <nothing> in supertype "Foo"
        return cls(a)

What is the actual behavior/output?

With mypy==0.720, this generates:

error: Return type "Baz" of "oof" incompatible with return type 

What is the behavior/output you expect?

Given that

class Baz(Foo[str]):
    pass

reveal_type(Baz.oof('1'))  # note: Revealed type is 'ack.Baz*' 

I would expect there to be no error when I override the classmethod in the subclass, so long as it is not conflicting.

On the other hand, I can work around this by

class Baz(Foo[str]):
    @classmethod
    def oof(cls: Type[Self], a: str) -> Self:
        return cls(a)

Have been spending some time looking at #6418 and related issues.

@JukkaL
Copy link
Collaborator

JukkaL commented Aug 29, 2019

I believe that this is technically a false positive. However, requiring the use of self types in all overrides seems kind of reasonable to me, so I wouldn't classify this as a bug but a missing feature.

The motivation for the check is that there could be a subclass of Baz that inherits oof from Baz, in which case mypy would be correct to complain (and incorrect to not complain). However, I think that this error condition could only be reported if there actually is a subclass of Baz that doesn't override oof.

@JukkaL
Copy link
Collaborator

JukkaL commented Aug 29, 2019

Closing as duplicate of #2511.

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

2 participants