You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Compatibility of return type with subclass upon overload #19952
Hi, we have the following minimal code snippet that reproduces our concern from pandas-dev/pandas-stubs#1385. In words, when the return types from different overloads are parametrised by a type variable, type checkers can work. When return types are subclasses, however, mypy does not seem to work.
fromtypingimportAny, Generic, Never, TypeVar, overload, reveal_typeT=TypeVar("T")
classArg(Generic[T]): ...
classGen(Generic[T]): ...
# part 1: return type is GenericclassD0:
@overloaddefm(self, p: Arg[Never]) ->Gen: ...
@overloaddefm(self, p: Arg[int]) ->Gen[int]: ...
reveal_type(D0().m(Arg[Any]())) # pyright gives Gen[Unknown], mypy gives Gen[Any], goodreveal_type(D0().m(Arg[int]())) # Gen[int], goodreveal_type(D0().m(Arg[float]())) # error, good# part 2: return types are subclassesclassBase: ...
classSub(Base): ...
classD1:
@overloaddefm(self, p: Arg[Never]) ->Base: ... # we want to get Base for Arg[Any]; mypy warns overload-overlap here, whereas pyright does not warn (at least without strict)@overloaddefm(self, p: Arg[int]) ->Sub: ...
reveal_type(D1().m(Arg[Any]())) # pyright gives Base, but mypy gives Anyreveal_type(D1().m(Arg[int]())) # Sub, goodreveal_type(D1().m(Arg[float]())) # error, good
Part 1 is understood from #19525. Could someone explain part 2? Thank you 🙂
When multiple overloads can be matched because of an Any argument(s), and the corresponding return types are not equivalent modulo Any, mypy intentionally infers Any as the result of the call. This is done to guarantee a fundamental rule of gradual typing: replacing a precise type with Any should not cause new errors. Consider this code:
a: Arg[Any] =Arg[int]()
x: Sub=D1().m(a)
this code would generate an error, while it shouldn't.
Activity
[-]Compatibility of return type upon overload[/-][+]Compatibility of return type with subclass upon overload[/+]ilevkivskyi commentedon Sep 29, 2025
When multiple overloads can be matched because of an
Anyargument(s), and the corresponding return types are not equivalent moduloAny, mypy intentionally infersAnyas the result of the call. This is done to guarantee a fundamental rule of gradual typing: replacing a precise type withAnyshould not cause new errors. Consider this code:this code would generate an error, while it shouldn't.
cmp0xff commentedon Oct 20, 2025
Hi @ilevkivskyi , thank you for triaging.
The complaint in the OP is that the return types should be considered as equivalent in the covariant sense, so that returning
Anyshould not happen.DOC: record confirmed mechanism and two failed fix attempts for the a…