Skip to content

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

Closed
@tyralla

Description

@tyralla

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions