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

Overloads in super-class for sub-class specific return types #11759

Closed
twoertwein opened this issue Dec 15, 2021 · 2 comments
Closed

Overloads in super-class for sub-class specific return types #11759

twoertwein opened this issue Dec 15, 2021 · 2 comments
Labels
feature topic-inheritance Inheritance and incompatible overrides topic-overloads

Comments

@twoertwein
Copy link

Bug Report
It is probably not good coding style to implement sub-class specific behavior in a super-class, but it would be great to still be able to write type annotations for it.

The sub-class specific overloads in the example below make mypy and pyright correctly infer the return type. Unfortunately, mypy throws an error for the two sub-class specific overloads. Are these false-positives?

To Reproduce

from __future__ import annotations

from typing import overload


class Base:
    @overload
    def any(self: A) -> bool:   # mypy:  The erased type of self "test.A" is not a supertype of its class "test.Base"
        ...

    @overload
    def any(self: B) -> str:  # mypy:  The erased type of self "test.B" is not a supertype of its class "test.Base"
        ...

    @overload
    def any(self) -> bool | str:
        ...

    def any(self) -> bool | str:
        # implementation that handles sub-classes differently
        ...


class A(Base):
    ...


class B(Base):
    ...


# mypy&pyright: bool | str
reveal_type(Base().any())

# mypy&pyright: bool
reveal_type(A().any())

# mypy&pyright: str
reveal_type(B().any())

Expected Behavior
No erased type errors?

Actual Behavior
See inline comments.

Your Environment

  • Mypy version used: 0.910
  • Mypy command-line flags: -
  • Mypy configuration options from mypy.ini (and other config files): -
  • Python version used: 3.9.6
  • Operating system and version: 3.10.0-693.5.2.el7.x86_64
@twoertwein twoertwein added the bug mypy got something wrong label Dec 15, 2021
@AlexWaygood AlexWaygood added feature topic-overloads topic-inheritance Inheritance and incompatible overrides and removed bug mypy got something wrong labels Mar 31, 2022
@AlexWaygood
Copy link
Member

Is this feature really necessary? You can achieve the same thing just by doing this:

from __future__ import annotations
from typing import Callable


class Base:
    def any(self) -> bool | str:
        # implementation that handles sub-classes differently
        ...


class A(Base):
    any: Callable[[A], bool]


class B(Base):
    any: Callable[[B], str]


reveal_type(Base().any())  # Revealed type is "Union[builtins.bool, builtins.str]"
reveal_type(A().any())  # Revealed type is "builtins.bool"
reveal_type(B().any())  # Revealed type is "builtins.str"

Mypy has no complaints, and it's even more concise.

@twoertwein
Copy link
Author

Thank you @AlexWaygood, I like it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature topic-inheritance Inheritance and incompatible overrides topic-overloads
Projects
None yet
Development

No branches or pull requests

2 participants