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

Multiple inheritance checks do not consider callable objects as possible subtypes of usual functions #14852

Closed
tyralla opened this issue Mar 7, 2023 · 0 comments · Fixed by #14855
Labels
bug mypy got something wrong

Comments

@tyralla
Copy link
Collaborator

tyralla commented Mar 7, 2023

It seems Mypy's method TypeChecker.check_compatibility for checking multiple inheritance compatibility does not consider that callable objects can be subtypes of usual functions, but method TypeChecker.check_method_override_for_base_with_name does so for single inheritance.

For the following example, Mypy reports:

  • Definition of "f" in base class "A1" is incompatible with definition in base class "A2" [misc]
  • Definition of "f" in base class "A2" is incompatible with definition in base class "A1" [misc]
from typing import Any, Callable, Self

class F:
    def __init__(self, f: Callable[[Any, int], int]) -> None:
        self.wrapped = f
        self.m: Any
    def __get__(self, obj: Any, objtype: Any) -> Self:
        self.m = obj
        return self
    def __call__(self, x: int) -> int:
        return self.wrapped(self, x)

def dec(f: Callable[[Any, int], int]) -> F:
    return F(f)

class A1:
    def f(self, x: int) -> int:
        return 1 * x

class B1(A1):  # no error reported, IMO okay
    @dec
    def f(self, x: int) -> int:
        return 2 * x

class A2:
    @dec
    def f(self, x: int) -> int:
        return 3 * x

class B21(A1, A2):  # error reported, IMO okay
    pass

class B22(A2, A1):  # error reported, IMO not okay
    pass

assert B1().f(1) == 2
assert B21().f(1) == 1
assert B22().f(1) == 3

assert hasattr(B1().f, "wrapped")
# assert hasattr(B21().f), "wrapped")  # would crash
assert hasattr(B22().f, "wrapped")
@tyralla tyralla added the bug mypy got something wrong label Mar 7, 2023
tyralla added a commit to tyralla/mypy that referenced this issue Mar 8, 2023
…ible subtypes of usual functions (Fixes python#14852).

The solution is inspired by the `visit_instance` method of `SubtypeVisitor`.  The `testMultipleInheritanceOverridingOfFunctionsWithCallableInstances` tests the new functionality for decorated and non-decorated functions and callable objects.
hauntsaninja pushed a commit that referenced this issue Mar 25, 2023
…ons (#14855)

Let the multiple inheritance checks consider callable objects as
possible subtypes of usual functions (Fixes #14852).

The solution is inspired by the `visit_instance` method of
`SubtypeVisitor`. The
`testMultipleInheritanceOverridingOfFunctionsWithCallableInstances`
tests the new functionality for decorated and non-decorated functions
and callable objects.
JukkaL pushed a commit that referenced this issue Apr 5, 2023
…ons (#14855)

Let the multiple inheritance checks consider callable objects as
possible subtypes of usual functions (Fixes #14852).

The solution is inspired by the `visit_instance` method of
`SubtypeVisitor`. The
`testMultipleInheritanceOverridingOfFunctionsWithCallableInstances`
tests the new functionality for decorated and non-decorated functions
and callable objects.
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
1 participant