From cb33390402c7f47e91daae94c3644463ae3849e8 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 1 Dec 2021 08:57:59 +0000 Subject: [PATCH 1/3] Improve operator.mod --- stdlib/_operator.pyi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index a945a0be74a4..5d5e6aebec4e 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,9 @@ class _SupportsNeg(Protocol[_T_co]): class _SupportsPos(Protocol[_T_co]): def __pos__(self) -> _T_co: ... +class _SupportsMod(Protocol[_T_contra, _T_co]): + def __mod__(self, x: _T_contra) -> _T_co: ... + # Different to _typeshed.SupportsLessThan class _SupportsLT(Protocol): def __lt__(self, other: Any) -> Any: ... @@ -68,7 +72,7 @@ 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: ... +def mod(__a: _SupportsMod[_T_contra, _T_co], __b: _T_contra) -> _T_co: ... def mul(__a: Any, __b: Any) -> Any: ... def matmul(__a: Any, __b: Any) -> Any: ... def neg(__a: _SupportsNeg[_T_co]) -> _T_co: ... From 74c160db86db453244f6073fde17eb42ba1ca64e Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 1 Dec 2021 11:08:19 +0000 Subject: [PATCH 2/3] Account for existence of `__rmod__` --- stdlib/_operator.pyi | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index 5d5e6aebec4e..d5527271b016 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -36,8 +36,14 @@ class _SupportsNeg(Protocol[_T_co]): class _SupportsPos(Protocol[_T_co]): def __pos__(self) -> _T_co: ... -class _SupportsMod(Protocol[_T_contra, _T_co]): - def __mod__(self, x: _T_contra) -> _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): @@ -52,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: ... @@ -72,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: _SupportsMod[_T_contra, _T_co], __b: _T_contra) -> _T_co: ... +@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: ... From e58d2373f165ef74164668184e14250db320f01a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 1 Dec 2021 11:09:23 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/_operator.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index d5527271b016..a81102200184 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -41,7 +41,7 @@ class _SupportsPos(Protocol[_T_co]): # 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: ...