diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index a945a0be74a4..a81102200184 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -22,6 +22,7 @@ from typing_extensions import ParamSpec, SupportsIndex, final _R = TypeVar("_R") _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) +_T_contra = TypeVar("_T_contra", contravariant=True) _K = TypeVar("_K") _V = TypeVar("_V") _P = ParamSpec("_P") @@ -35,6 +36,15 @@ class _SupportsNeg(Protocol[_T_co]): class _SupportsPos(Protocol[_T_co]): def __pos__(self) -> _T_co: ... +# We cannot specify the return type in _SupportsMod & _SupportsRMod +# because whether __mod__ or __rmod__ is called first depends +# on whether the rhs operand is a subclass of the lhs operand. +class _SupportsMod(Protocol[_T_contra]): + def __mod__(self, x: _T_contra) -> Any: ... + +class _SupportsRMod(Protocol[_T_contra]): + def __rmod__(self, x: _T_contra) -> Any: ... + # Different to _typeshed.SupportsLessThan class _SupportsLT(Protocol): def __lt__(self, other: Any) -> Any: ... @@ -48,6 +58,8 @@ class _SupportsLE(Protocol): class _SupportsGE(Protocol): def __ge__(self, other: Any) -> Any: ... +# We have to use a union as we get false-positive errors +# if `lt`/`le`/`gt`/`ge` do not all have the same signature. _SupportsComparison = Union[_SupportsLE, _SupportsGE, _SupportsGT, _SupportsLT] def lt(__a: _SupportsComparison, __b: _SupportsComparison) -> Any: ... @@ -68,7 +80,10 @@ def index(__a: SupportsIndex) -> int: ... def inv(__a: _SupportsInversion[_T_co]) -> _T_co: ... def invert(__a: _SupportsInversion[_T_co]) -> _T_co: ... def lshift(__a: Any, __b: Any) -> Any: ... -def mod(__a: Any, __b: Any) -> Any: ... +@overload +def mod(__a: _SupportsMod[_T_contra], __b: _T_contra) -> Any: ... +@overload +def mod(__a: _T_contra, __b: _SupportsRMod[_T_contra]) -> Any: ... def mul(__a: Any, __b: Any) -> Any: ... def matmul(__a: Any, __b: Any) -> Any: ... def neg(__a: _SupportsNeg[_T_co]) -> _T_co: ...