From 61ace76217b83e1c134ba498ba5d078bfcee5250 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 2 Apr 2026 11:11:43 +0200 Subject: [PATCH 1/6] [_operator] Remove `Any`s that can be improved --- stdlib/_operator.pyi | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index e1ef5c4bf067..62ed3917b76f 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -58,24 +58,24 @@ def truth(a: object, /) -> bool: ... def is_(a: object, b: object, /) -> bool: ... def is_not(a: object, b: object, /) -> bool: ... def abs(a: SupportsAbs[_T], /) -> _T: ... -def add(a: Any, b: Any, /) -> Any: ... -def and_(a: Any, b: Any, /) -> Any: ... -def floordiv(a: Any, b: Any, /) -> Any: ... +def add(a, b, /): ... +def and_(a, b, /): ... +def floordiv(a, b, /): ... 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 mul(a: Any, b: Any, /) -> Any: ... -def matmul(a: Any, b: Any, /) -> Any: ... +def lshift(a, b, /): ... +def mod(a, b, /): ... +def mul(a, b, /): ... +def matmul(a, b, /): ... def neg(a: _SupportsNeg[_T_co], /) -> _T_co: ... -def or_(a: Any, b: Any, /) -> Any: ... +def or_(a, b, /): ... def pos(a: _SupportsPos[_T_co], /) -> _T_co: ... -def pow(a: Any, b: Any, /) -> Any: ... -def rshift(a: Any, b: Any, /) -> Any: ... -def sub(a: Any, b: Any, /) -> Any: ... -def truediv(a: Any, b: Any, /) -> Any: ... -def xor(a: Any, b: Any, /) -> Any: ... +def pow(a, b, /): ... +def rshift(a, b, /): ... +def sub(a, b, /): ... +def truediv(a, b, /): ... +def xor(a, b, /): ... def concat(a: Sequence[_T], b: Sequence[_T], /) -> Sequence[_T]: ... def contains(a: Container[object], b: object, /) -> bool: ... def countOf(a: Iterable[object], b: object, /) -> int: ... @@ -97,20 +97,20 @@ def setitem(a: MutableSequence[_T], b: slice[int | None], c: Sequence[_T], /) -> @overload def setitem(a: MutableMapping[_K, _V], b: _K, c: _V, /) -> None: ... def length_hint(obj: object, default: int = 0, /) -> int: ... -def iadd(a: Any, b: Any, /) -> Any: ... -def iand(a: Any, b: Any, /) -> Any: ... -def iconcat(a: Any, b: Any, /) -> Any: ... -def ifloordiv(a: Any, b: Any, /) -> Any: ... -def ilshift(a: Any, b: Any, /) -> Any: ... -def imod(a: Any, b: Any, /) -> Any: ... -def imul(a: Any, b: Any, /) -> Any: ... -def imatmul(a: Any, b: Any, /) -> Any: ... -def ior(a: Any, b: Any, /) -> Any: ... -def ipow(a: Any, b: Any, /) -> Any: ... -def irshift(a: Any, b: Any, /) -> Any: ... -def isub(a: Any, b: Any, /) -> Any: ... -def itruediv(a: Any, b: Any, /) -> Any: ... -def ixor(a: Any, b: Any, /) -> Any: ... +def iadd(a, b, /): ... +def iand(a, b, /): ... +def iconcat(a, b, /): ... +def ifloordiv(a, b, /): ... +def ilshift(a, b, /): ... +def imod(a, b, /): ... +def imul(a, b, /): ... +def imatmul(a, b, /): ... +def ior(a, b, /): ... +def ipow(a, b, /): ... +def irshift(a, b, /): ... +def isub(a, b, /): ... +def itruediv(a, b, /): ... +def ixor(a, b, /): ... if sys.version_info >= (3, 11): def call(obj: Callable[_P, _R], /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ... From 98baf2b1719d12f926b660b67cb3b5a3c6fb0f9d Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 2 Apr 2026 11:16:26 +0200 Subject: [PATCH 2/6] Exclude `_operator.pyi` from stricter pyright config --- pyrightconfig.stricter.json | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index cf57f92f0df2..df74bb3e19c5 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -9,6 +9,7 @@ // test cases use a custom pyrightconfig file "**/@tests/test_cases", "stdlib/__main__.pyi", + "stdlib/_operator.pyi", "stdlib/_tkinter.pyi", "stdlib/distutils/cmd.pyi", "stdlib/distutils/command", From 2484392fb8dedcc4c1f6233a760939c8dce79379 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 2 Apr 2026 11:32:58 +0200 Subject: [PATCH 3/6] Add `operator.pyi` as well --- pyrightconfig.stricter.json | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index df74bb3e19c5..223f0b415e45 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -17,6 +17,7 @@ "stdlib/encodings/__init__.pyi", "stdlib/lib2to3/fixes/*.pyi", "stdlib/numbers.pyi", + "stdlib/operator.pyi", "stdlib/tkinter/__init__.pyi", "stdlib/tkinter/dialog.pyi", "stdlib/tkinter/filedialog.pyi", From 563ee38339053a56c5130453b0567e88061c7cbd Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 2 Apr 2026 11:54:26 +0200 Subject: [PATCH 4/6] Type `mul` to satisfy a test --- stdlib/_operator.pyi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index 62ed3917b76f..f2dbcfd8f027 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -8,6 +8,7 @@ from typing_extensions import ParamSpec, TypeAlias, TypeIs _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") @@ -38,6 +39,10 @@ _SupportsComparison: TypeAlias = _SupportsDunderLE | _SupportsDunderGE | _Suppor class _SupportsInversion(Protocol[_T_co]): def __invert__(self) -> _T_co: ... +@type_check_only +class _SupportsMul(Protocol[_T_co, _T_contra]): + def __mul__(self, other: _T_contra, /) -> _T_co: ... + @type_check_only class _SupportsNeg(Protocol[_T_co]): def __neg__(self) -> _T_co: ... @@ -66,7 +71,7 @@ def inv(a: _SupportsInversion[_T_co], /) -> _T_co: ... def invert(a: _SupportsInversion[_T_co], /) -> _T_co: ... def lshift(a, b, /): ... def mod(a, b, /): ... -def mul(a, b, /): ... +def mul(a: _SupportsMul[_T_co, _T_contra], b: _T_contra, /) -> _T_co: ... def matmul(a, b, /): ... def neg(a: _SupportsNeg[_T_co], /) -> _T_co: ... def or_(a, b, /): ... From f0e725ad943f2226ca95797d0af70f4e7afa024b Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 2 Apr 2026 12:09:01 +0200 Subject: [PATCH 5/6] Support __rmul__ --- stdlib/_operator.pyi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index f2dbcfd8f027..bc5be07b8050 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -43,6 +43,10 @@ class _SupportsInversion(Protocol[_T_co]): class _SupportsMul(Protocol[_T_co, _T_contra]): def __mul__(self, other: _T_contra, /) -> _T_co: ... +@type_check_only +class _SupportsRMul(Protocol[_T_co, _T_contra]): + def __rmul__(self, other: _T_contra, /) -> _T_co: ... + @type_check_only class _SupportsNeg(Protocol[_T_co]): def __neg__(self) -> _T_co: ... @@ -71,7 +75,10 @@ def inv(a: _SupportsInversion[_T_co], /) -> _T_co: ... def invert(a: _SupportsInversion[_T_co], /) -> _T_co: ... def lshift(a, b, /): ... def mod(a, b, /): ... +@overload def mul(a: _SupportsMul[_T_co, _T_contra], b: _T_contra, /) -> _T_co: ... +@overload +def mul(a: _T_contra, b: _SupportsRMul[_T_co, _T_contra], /) -> _T_co: ... def matmul(a, b, /): ... def neg(a: _SupportsNeg[_T_co], /) -> _T_co: ... def or_(a, b, /): ... From 34aebf15567879f37a1e474ef42d974eef05379f Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 2 Apr 2026 12:18:42 +0200 Subject: [PATCH 6/6] Use protocols from _typeshed --- stdlib/_operator.pyi | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index bc5be07b8050..83344c7f96c8 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import SupportsGetItem +from _typeshed import SupportsGetItem, SupportsMul, SupportsRMul from collections.abc import Callable, Container, Iterable, MutableMapping, MutableSequence, Sequence from operator import attrgetter as attrgetter, itemgetter as itemgetter, methodcaller as methodcaller from typing import Any, AnyStr, Protocol, SupportsAbs, SupportsIndex, TypeVar, overload, type_check_only @@ -39,14 +39,6 @@ _SupportsComparison: TypeAlias = _SupportsDunderLE | _SupportsDunderGE | _Suppor class _SupportsInversion(Protocol[_T_co]): def __invert__(self) -> _T_co: ... -@type_check_only -class _SupportsMul(Protocol[_T_co, _T_contra]): - def __mul__(self, other: _T_contra, /) -> _T_co: ... - -@type_check_only -class _SupportsRMul(Protocol[_T_co, _T_contra]): - def __rmul__(self, other: _T_contra, /) -> _T_co: ... - @type_check_only class _SupportsNeg(Protocol[_T_co]): def __neg__(self) -> _T_co: ... @@ -76,9 +68,9 @@ def invert(a: _SupportsInversion[_T_co], /) -> _T_co: ... def lshift(a, b, /): ... def mod(a, b, /): ... @overload -def mul(a: _SupportsMul[_T_co, _T_contra], b: _T_contra, /) -> _T_co: ... +def mul(a: SupportsMul[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... @overload -def mul(a: _T_contra, b: _SupportsRMul[_T_co, _T_contra], /) -> _T_co: ... +def mul(a: _T_contra, b: SupportsRMul[_T_contra, _T_co], /) -> _T_co: ... def matmul(a, b, /): ... def neg(a: _SupportsNeg[_T_co], /) -> _T_co: ... def or_(a, b, /): ...