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

Incompatible signature in method with restricted overload for a generic class #12151

Closed
vnmabus opened this issue Feb 8, 2022 · 6 comments
Closed
Labels
bug mypy got something wrong

Comments

@vnmabus
Copy link

vnmabus commented Feb 8, 2022

Bug Report

When a method of a generic class has an overload for a particular type of the generic parameter, subclasses that don't have that particular value should be able to override the method without that overload, but currently aren't.

To Reproduce

Consider the following code:

T = TypeVar("T")
A_no_T = TypeVar(
    "A_no_T",
    bound="A[None]",
)


class A(
    Generic[T],
):

    @overload
    def method(
        self: A_no_T,
    ) -> None:
        pass

    @overload
    def method(
        self,
        t: T,
    ) -> None:
        pass

    def method(
        self,
        t: Optional[T] = None,
    ) -> None:
        return


class B(A[int]):

    def method(
        self,
        t: int,
    ) -> None:
        pass

Expected Behavior

The code should typecheck without errors.

Actual Behavior

The following error is raised

Mypy: Signature of "method" incompatible with supertype "A"  [override]
Superclass:
@overload
def method(self) -> None
@overload
def method(self, t: int) -> None
Subclass:
def method(self, t: int) -> None

Your Environment

  • Mypy version used: 0.931
  • Mypy command-line flags: --follow-imports=silent --show-column-numbers --show-error-codes
  • Mypy configuration options from mypy.ini (and other config files):
    strict = True
    strict_equality = True
    implicit_reexport = True
  • Python version used: 3.8.0
  • Operating system and version: Linux Ubuntu 18.04.6 LTS
@vnmabus vnmabus added the bug mypy got something wrong label Feb 8, 2022
@erictraut
Copy link

erictraut commented Feb 8, 2022

I don't think that's generally safe. What if the base class A contains the following?

    x: T

    def other_method(self):
        self.method(self.x)

Now if you call B().other_method(), the function B.method will get called with a None argument.

The problem is that when analyzing A, we don't know whether T has been bound to None, so the trick you're using to detect A[None] doesn't work in this case.

@vnmabus
Copy link
Author

vnmabus commented Feb 8, 2022

Sorry, but I don't get it. Surely x should have an int value in B, no?

@erictraut
Copy link

Sorry, forget what I said. My analysis was incorrect.

I think the issue is that mypy is validating the method implementation signature in the child class against the implementation signature in the parent class, but you want it to take into account the overload signatures in the child class as well.

@vnmabus
Copy link
Author

vnmabus commented Feb 8, 2022

Yeah, I think that is something sensible to do. In fact, requiring me to provide the first overload is wrong.

@erictraut
Copy link

I think this bug has been fixed. The latest version of mypy (1.5) no longer generates an error.

@hauntsaninja
Copy link
Collaborator

I fixed this in #14882

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

3 participants