diff --git a/mypy/checker.py b/mypy/checker.py index 6cee4a633baf..8b17360028f6 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3557,7 +3557,7 @@ def is_unsafe_overlapping_signatures(signature: Type, other: Type) -> bool: # Special case: all args are subtypes, and returns are subtypes if (all(is_proper_subtype(s, o) for (s, o) in zip(signature.arg_types, other.arg_types)) and - is_proper_subtype(signature.ret_type, other.ret_type)): + is_subtype(signature.ret_type, other.ret_type)): return False return not is_more_precise_signature(signature, other) return True diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index 88eabcaf4a61..8450aedcec23 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -1490,3 +1490,17 @@ class Child4(ParentWithDynamicImpl): [builtins fixtures/tuple.pyi] +[case testOverloadAnyIsConsideredValidReturnSubtype] +from typing import Any, overload, Optional + +@overload +def foo(x: None) -> Any: ... +@overload +def foo(x: Optional[str]) -> str: ... +def foo(x): pass + +@overload +def bar(x: None) -> object: ... # E: Overloaded function signatures 1 and 2 overlap with incompatible return types +@overload +def bar(x: Optional[str]) -> str: ... +def bar(x): pass diff --git a/test-data/unit/lib-stub/attr.pyi b/test-data/unit/lib-stub/attr.pyi index 8118743f8234..cc4047ccfb94 100644 --- a/test-data/unit/lib-stub/attr.pyi +++ b/test-data/unit/lib-stub/attr.pyi @@ -8,6 +8,20 @@ _ConverterType = Callable[[Any], _T] _FilterType = Callable[[Any, Any], bool] _ValidatorArgType = Union[_ValidatorType[_T], Sequence[_ValidatorType[_T]]] +# This form catches explicit None or no default but with no other arguments returns Any. +@overload +def attrib(default: None = ..., + validator: None = ..., + repr: bool = ..., + cmp: bool = ..., + hash: Optional[bool] = ..., + init: bool = ..., + convert: None = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: None = ..., + converter: None = ..., + factory: None = ..., + ) -> Any: ... # This form catches an explicit None or no default and infers the type from the other arguments. @overload def attrib(default: None = ..., @@ -36,20 +50,6 @@ def attrib(default: _T, converter: Optional[_ConverterType[_T]] = ..., factory: Optional[Callable[[], _T]] = ..., ) -> _T: ... -# This form catches explicit None or no default but with no other arguments returns Any. -@overload -def attrib(default: None = ..., - validator: None = ..., - repr: bool = ..., - cmp: bool = ..., - hash: Optional[bool] = ..., - init: bool = ..., - convert: None = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - type: None = ..., - converter: None = ..., - factory: None = ..., - ) -> Any: ... # This form covers type=non-Type: e.g. forward references (str), Any @overload def attrib(default: Optional[_T] = ...,