Skip to content

Commit

Permalink
Bind self to the class being defined when checking multiple inheritan…
Browse files Browse the repository at this point in the history
…ce (#18465)

Fixes #18458. 

When checking base class compatibility, the class being defined is not
yet in scope. However, it should be equivalent to the class passed to
`bind_and_map_method` with free typevars, as that's exactly what we are
currently defining.
  • Loading branch information
sterliakov authored Jan 14, 2025
1 parent 9fffd9e commit b68c545
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
4 changes: 2 additions & 2 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2232,8 +2232,8 @@ def bind_and_map_method(
is_class_method = sym.node.is_class

mapped_typ = cast(FunctionLike, map_type_from_supertype(typ, sub_info, super_info))
active_self_type = self.scope.active_self_type()
if isinstance(mapped_typ, Overloaded) and active_self_type:
active_self_type = fill_typevars(sub_info)
if isinstance(mapped_typ, Overloaded):
# If we have an overload, filter to overloads that match the self type.
# This avoids false positives for concrete subclasses of generic classes,
# see testSelfTypeOverrideCompatibility for an example.
Expand Down
19 changes: 19 additions & 0 deletions test-data/unit/check-selftype.test
Original file line number Diff line number Diff line change
Expand Up @@ -2214,3 +2214,22 @@ class Test2:

reveal_type(Test2().method) # N: Revealed type is "def (foo: builtins.int, *, bar: builtins.str) -> builtins.bytes"
[builtins fixtures/tuple.pyi]

[case testSelfInMultipleInheritance]
from typing_extensions import Self

class A:
foo: int
def method(self: Self, other: Self) -> None:
self.foo
other.foo

class B:
bar: str
def method(self: Self, other: Self) -> None:
self.bar
other.bar

class C(A, B): # OK: both methods take Self
pass
[builtins fixtures/tuple.pyi]

0 comments on commit b68c545

Please sign in to comment.