Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite2e5d7f

Browse files
authored
Fix incompatible overrides of overloaded generics with self types (#14882)
Fixes#14866Basically does the potential todo I'd mentioned in#14017
1 parentfb6b8bc commite2e5d7f

File tree

2 files changed

+45
-20
lines changed

2 files changed

+45
-20
lines changed

‎mypy/checker.py‎

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,23 +1876,6 @@ def check_method_override_for_base_with_name(
18761876
original_class_or_static=False# a variable can't be class or static
18771877

18781878
ifisinstance(original_type,FunctionLike):
1879-
active_self_type=self.scope.active_self_type()
1880-
ifisinstance(original_type,Overloaded)andactive_self_type:
1881-
# If we have an overload, filter to overloads that match the self type.
1882-
# This avoids false positives for concrete subclasses of generic classes,
1883-
# see testSelfTypeOverrideCompatibility for an example.
1884-
# It's possible we might want to do this as part of bind_and_map_method
1885-
filtered_items= [
1886-
item
1887-
foriteminoriginal_type.items
1888-
ifnotitem.arg_typesoris_subtype(active_self_type,item.arg_types[0])
1889-
]
1890-
# If we don't have any filtered_items, maybe it's always a valid override
1891-
# of the superclass? However if you get to that point you're in murky type
1892-
# territory anyway, so we just preserve the type and have the behaviour match
1893-
# that of older versions of mypy.
1894-
iffiltered_items:
1895-
original_type=Overloaded(filtered_items)
18961879
original_type=self.bind_and_map_method(base_attr,original_type,defn.info,base)
18971880
iforiginal_nodeandis_property(original_node):
18981881
original_type=get_property_type(original_type)
@@ -1964,10 +1947,28 @@ def bind_and_map_method(
19641947
is_class_method=sym.node.func.is_class
19651948
else:
19661949
is_class_method=sym.node.is_class
1967-
bound=bind_self(typ,self.scope.active_self_type(),is_class_method)
1950+
1951+
mapped_typ=cast(FunctionLike,map_type_from_supertype(typ,sub_info,super_info))
1952+
active_self_type=self.scope.active_self_type()
1953+
ifisinstance(mapped_typ,Overloaded)andactive_self_type:
1954+
# If we have an overload, filter to overloads that match the self type.
1955+
# This avoids false positives for concrete subclasses of generic classes,
1956+
# see testSelfTypeOverrideCompatibility for an example.
1957+
filtered_items= [
1958+
item
1959+
foriteminmapped_typ.items
1960+
ifnotitem.arg_typesoris_subtype(active_self_type,item.arg_types[0])
1961+
]
1962+
# If we don't have any filtered_items, maybe it's always a valid override
1963+
# of the superclass? However if you get to that point you're in murky type
1964+
# territory anyway, so we just preserve the type and have the behaviour match
1965+
# that of older versions of mypy.
1966+
iffiltered_items:
1967+
mapped_typ=Overloaded(filtered_items)
1968+
1969+
returnbind_self(mapped_typ,active_self_type,is_class_method)
19681970
else:
1969-
bound=typ
1970-
returncast(FunctionLike,map_type_from_supertype(bound,sub_info,super_info))
1971+
returncast(FunctionLike,map_type_from_supertype(typ,sub_info,super_info))
19711972

19721973
defget_op_other_domain(self,tp:FunctionLike)->Type|None:
19731974
ifisinstance(tp,CallableType):

‎test-data/unit/check-selftype.test‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,30 @@ class J(A[int]):
208208

209209
[builtins fixtures/tuple.pyi]
210210

211+
[case testSelfTypeOverrideCompatibilityGeneric]
212+
from typing import TypeVar, Generic, overload
213+
214+
T = TypeVar("T", str, int, None)
215+
216+
class A(Generic[T]):
217+
@overload
218+
def f(self, s: T) -> T: ...
219+
@overload
220+
def f(self: A[str], s: bytes) -> str: ...
221+
def f(self, s: object): ...
222+
223+
class B(A[int]):
224+
def f(self, s: int) -> int: ...
225+
226+
class C(A[None]):
227+
def f(self, s: int) -> int: ... # E: Signature of "f" incompatible with supertype "A" \
228+
# N: Superclass: \
229+
# N: @overload \
230+
# N: def f(self, s: None) -> None \
231+
# N: Subclass: \
232+
# N: def f(self, s: int) -> int
233+
[builtins fixtures/tuple.pyi]
234+
211235
[case testSelfTypeOverrideCompatibilityTypeVar-xfail]
212236
from typing import overload, TypeVar, Union
213237

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp