Skip to content

Commit 3d9661c

Browse files
authored
Fix bounded self types in override incompatibility checking (#15045)
Fixes #15041 Related to #14882 and #14017 (the older one is where I added the xfail test)
1 parent 0799a8a commit 3d9661c

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

Diff for: mypy/checker.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -1954,11 +1954,15 @@ def bind_and_map_method(
19541954
# If we have an overload, filter to overloads that match the self type.
19551955
# This avoids false positives for concrete subclasses of generic classes,
19561956
# see testSelfTypeOverrideCompatibility for an example.
1957-
filtered_items = [
1958-
item
1959-
for item in mapped_typ.items
1960-
if not item.arg_types or is_subtype(active_self_type, item.arg_types[0])
1961-
]
1957+
filtered_items = []
1958+
for item in mapped_typ.items:
1959+
if not item.arg_types:
1960+
filtered_items.append(item)
1961+
item_arg = item.arg_types[0]
1962+
if isinstance(item_arg, TypeVarType):
1963+
item_arg = item_arg.upper_bound
1964+
if is_subtype(active_self_type, item_arg):
1965+
filtered_items.append(item)
19621966
# If we don't have any filtered_items, maybe it's always a valid override
19631967
# of the superclass? However if you get to that point you're in murky type
19641968
# territory anyway, so we just preserve the type and have the behaviour match

Diff for: test-data/unit/check-selftype.test

+21-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ class C(A[None]):
232232
# N: def f(self, s: int) -> int
233233
[builtins fixtures/tuple.pyi]
234234

235-
[case testSelfTypeOverrideCompatibilityTypeVar-xfail]
235+
[case testSelfTypeOverrideCompatibilityTypeVar]
236236
from typing import overload, TypeVar, Union
237237

238238
AT = TypeVar("AT", bound="A")
@@ -266,6 +266,26 @@ class B(A):
266266
def f(*a, **kw): ...
267267
[builtins fixtures/dict.pyi]
268268

269+
[case testSelfTypeOverrideCompatibilitySelfTypeVar]
270+
from typing import Any, Generic, Self, TypeVar, overload
271+
272+
T_co = TypeVar('T_co', covariant=True)
273+
274+
class Config(Generic[T_co]):
275+
@overload
276+
def get(self, instance: None) -> Self: ...
277+
@overload
278+
def get(self, instance: Any) -> T_co: ...
279+
def get(self, *a, **kw): ...
280+
281+
class MultiConfig(Config[T_co]):
282+
@overload
283+
def get(self, instance: None) -> Self: ...
284+
@overload
285+
def get(self, instance: Any) -> T_co: ...
286+
def get(self, *a, **kw): ...
287+
[builtins fixtures/dict.pyi]
288+
269289
[case testSelfTypeSuper]
270290
from typing import TypeVar, cast
271291

0 commit comments

Comments
 (0)