Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,9 @@ def _visit_func_def(self, defn: FuncDef) -> None:
"""Type check a function definition."""
self.check_func_item(defn, name=defn.name())
if defn.info:
if not defn.is_dynamic():
if not defn.is_dynamic() and not defn.is_overload:
# If the definition is the implementation for an overload, the legality
# of the override has already been typechecked.
self.check_method_override(defn)
self.check_inplace_operator_method(defn)
if defn.original_def:
Expand Down
91 changes: 91 additions & 0 deletions test-data/unit/check-overloading.test
Original file line number Diff line number Diff line change
Expand Up @@ -1399,3 +1399,94 @@ def g(x: Tuple[A, B]) -> D: ...
def g(x: Any) -> Any:...

[builtins fixtures/tuple.pyi]

[case testOverloadWithMethodOverrideAndImplementation]
from typing import overload, Union, Any

class Parent:
@overload
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: str) -> str: ...
def f(self, arg: Any) -> Any: ...

class Child1(Parent):
@overload
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: str) -> str: ...
def f(self, arg: Union[int, str]) -> Union[int, str]: ...

class Child2(Parent):
@overload
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: str) -> str: ...
def f(self, arg: Union[int, str]) -> int: ... # E: Overloaded function implementation cannot produce return type of signature 2

class Child3(Parent):
@overload
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: str) -> str: ...
def f(self, arg: Any) -> Any: ...

class Child4(Parent):
@overload
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: str) -> str: ...
def f(self, arg: Union[int, str]) -> Union[int, str]:
return True # E: Incompatible return value type (got "bool", expected "Union[int, str]")

[builtins fixtures/tuple.pyi]

[case testOverloadWithIncompatibleMethodOverrideAndImplementation]
from typing import overload, Union, Any

class StrSub: pass

class ParentWithTypedImpl:
@overload
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: str) -> str: ...
def f(self, arg: Union[int, str]) -> Union[int, str]: ...

class Child1(ParentWithTypedImpl):
@overload # E: Signature of "f" incompatible with supertype "ParentWithTypedImpl"
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: StrSub) -> str: ...
def f(self, arg: Union[int, StrSub]) -> Union[int, str]: ...

class Child2(ParentWithTypedImpl):
@overload # E: Signature of "f" incompatible with supertype "ParentWithTypedImpl"
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: StrSub) -> str: ...
def f(self, arg: Any) -> Any: ...

class ParentWithDynamicImpl:
@overload
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: str) -> str: ...
def f(self, arg: Any) -> Any: ...

class Child3(ParentWithDynamicImpl):
@overload # E: Signature of "f" incompatible with supertype "ParentWithDynamicImpl"
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: StrSub) -> str: ...
def f(self, arg: Union[int, StrSub]) -> Union[int, str]: ...

class Child4(ParentWithDynamicImpl):
@overload # E: Signature of "f" incompatible with supertype "ParentWithDynamicImpl"
def f(self, arg: int) -> int: ...
@overload
def f(self, arg: StrSub) -> str: ...
def f(self, arg: Any) -> Any: ...

[builtins fixtures/tuple.pyi]