Closed
Description
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")