diff --git a/stdlib/_operator.pyi b/stdlib/_operator.pyi index e7d85f811531..41b949d52e3b 100644 --- a/stdlib/_operator.pyi +++ b/stdlib/_operator.pyi @@ -1,18 +1,21 @@ import sys from _typeshed import ( SupportsAdd, + SupportsBool, + SupportsDunderGE, + SupportsDunderGT, + SupportsDunderLE, + SupportsDunderLT, SupportsGetItem, - SupportsMod, SupportsMul, SupportsRAdd, - SupportsRMod, SupportsRMul, SupportsRSub, SupportsSub, ) 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 +from typing import Any, Protocol, SupportsAbs, SupportsIndex, TypeVar, overload, type_check_only from typing_extensions import ParamSpec, TypeAlias, TypeIs _R = TypeVar("_R") @@ -23,39 +26,151 @@ _K = TypeVar("_K") _V = TypeVar("_V") _P = ParamSpec("_P") -# The following protocols return "Any" instead of bool, since the comparison -# operators can be overloaded to return an arbitrary object. For example, -# the numpy.array comparison dunders return another numpy.array. +_SupportsComparison: TypeAlias = SupportsDunderLE[Any] | SupportsDunderGE[Any] | SupportsDunderGT[Any] | SupportsDunderLT[Any] @type_check_only -class _SupportsDunderLT(Protocol): - def __lt__(self, other: Any, /) -> Any: ... +class _SupportsInversion(Protocol[_T_co]): + def __invert__(self) -> _T_co: ... @type_check_only -class _SupportsDunderGT(Protocol): - def __gt__(self, other: Any, /) -> Any: ... +class _SupportsNeg(Protocol[_T_co]): + def __neg__(self) -> _T_co: ... @type_check_only -class _SupportsDunderLE(Protocol): - def __le__(self, other: Any, /) -> Any: ... +class _SupportsPos(Protocol[_T_co]): + def __pos__(self) -> _T_co: ... @type_check_only -class _SupportsDunderGE(Protocol): - def __ge__(self, other: Any, /) -> Any: ... +class _SupportsAnd(Protocol[_T_contra, _T_co]): + def __and__(self, other: _T_contra) -> _T_co: ... -_SupportsComparison: TypeAlias = _SupportsDunderLE | _SupportsDunderGE | _SupportsDunderGT | _SupportsDunderLT +@type_check_only +class _SupportsRAnd(Protocol[_T_contra, _T_co]): + def __rand__(self, other: _T_contra) -> _T_co: ... @type_check_only -class _SupportsInversion(Protocol[_T_co]): - def __invert__(self) -> _T_co: ... +class _SupportsLShift(Protocol[_T_contra, _T_co]): + def __lshift__(self, other: _T_contra) -> _T_co: ... @type_check_only -class _SupportsNeg(Protocol[_T_co]): - def __neg__(self) -> _T_co: ... +class _SupportsRLShift(Protocol[_T_contra, _T_co]): + def __rlshift__(self, other: _T_contra) -> _T_co: ... @type_check_only -class _SupportsPos(Protocol[_T_co]): - def __pos__(self) -> _T_co: ... +class _SupportsRShift(Protocol[_T_contra, _T_co]): + def __rshift__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsRRShift(Protocol[_T_contra, _T_co]): + def __rrshift__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsTrueDiv(Protocol[_T_contra, _T_co]): + def __truediv__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsRTrueDiv(Protocol[_T_contra, _T_co]): + def __rtruediv__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsFloorDiv(Protocol[_T_contra, _T_co]): + def __floordiv__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsRFloorDiv(Protocol[_T_contra, _T_co]): + def __rfloordiv__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsMod(Protocol[_T_contra, _T_co]): + def __mod__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsRMod(Protocol[_T_contra, _T_co]): + def __rmod__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsMatMul(Protocol[_T_contra, _T_co]): + def __matmul__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsRMatMul(Protocol[_T_contra, _T_co]): + def __rmatmul__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsOr(Protocol[_T_contra, _T_co]): + def __or__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsROr(Protocol[_T_contra, _T_co]): + def __ror__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsPow(Protocol[_T_contra, _T_co]): + def __pow__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsRPow(Protocol[_T_contra, _T_co]): + def __rpow__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsXOr(Protocol[_T_contra, _T_co]): + def __xor__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsRXOr(Protocol[_T_contra, _T_co]): + def __rxor__(self, other: _T_contra) -> _T_co: ... + +@type_check_only +class _SupportsIAdd(Protocol[_T_contra, _T_co]): + def __iadd__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIAnd(Protocol[_T_contra, _T_co]): + def __iand__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsILShift(Protocol[_T_contra, _T_co]): + def __ilshift__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIMod(Protocol[_T_contra, _T_co]): + def __imod__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIMul(Protocol[_T_contra, _T_co]): + def __imul__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIMatMul(Protocol[_T_contra, _T_co]): + def __imatmul__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIOr(Protocol[_T_contra, _T_co]): + def __ior__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIPow(Protocol[_T_contra, _T_co]): + def __ipow__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIRShift(Protocol[_T_contra, _T_co]): + def __irshift__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsISub(Protocol[_T_contra, _T_co]): + def __isub__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsITrueDiv(Protocol[_T_contra, _T_co]): + def __itruediv__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIXOr(Protocol[_T_contra, _T_co]): + def __ixor__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 + +@type_check_only +class _SupportsIFloorDiv(Protocol[_T_contra, _T_co]): + def __ifloordiv__(self, other: _T_contra) -> _T_co: ... # noqa: Y034 # All four comparison functions must have the same signature, or we get false-positive errors def lt(a: _SupportsComparison, b: _SupportsComparison, /) -> Any: ... @@ -64,8 +179,8 @@ def eq(a: object, b: object, /) -> Any: ... def ne(a: object, b: object, /) -> Any: ... def ge(a: _SupportsComparison, b: _SupportsComparison, /) -> Any: ... def gt(a: _SupportsComparison, b: _SupportsComparison, /) -> Any: ... -def not_(a: object, /) -> bool: ... -def truth(a: object, /) -> bool: ... +def not_(a: SupportsBool, /) -> bool: ... +def truth(a: SupportsBool, /) -> bool: ... def is_(a: object, b: object, /) -> bool: ... def is_not(a: object, b: object, /) -> bool: ... def abs(a: SupportsAbs[_T], /) -> _T: ... @@ -73,32 +188,59 @@ def abs(a: SupportsAbs[_T], /) -> _T: ... def add(a: SupportsAdd[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... @overload def add(a: _T_contra, b: SupportsRAdd[_T_contra, _T_co], /) -> _T_co: ... -def and_(a, b, /): ... -def floordiv(a, b, /): ... +@overload +def and_(a: _SupportsAnd[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def and_(a: _T_contra, b: _SupportsRAnd[_T_contra, _T_co], /) -> _T_co: ... +@overload +def floordiv(a: _SupportsFloorDiv[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def floordiv(a: _T_contra, b: _SupportsRFloorDiv[_T_contra, _T_co], /) -> _T_co: ... def index(a: SupportsIndex, /) -> int: ... def inv(a: _SupportsInversion[_T_co], /) -> _T_co: ... def invert(a: _SupportsInversion[_T_co], /) -> _T_co: ... -def lshift(a, b, /): ... @overload -def mod(a: SupportsMod[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +def lshift(a: _SupportsLShift[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def lshift(a: _T_contra, b: _SupportsRLShift[_T_contra, _T_co], /) -> _T_co: ... @overload -def mod(a: _T_contra, b: SupportsRMod[_T_contra, _T_co], /) -> _T_co: ... +def mod(a: _SupportsMod[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def mod(a: _T_contra, b: _SupportsRMod[_T_contra, _T_co], /) -> _T_co: ... @overload def mul(a: SupportsMul[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... @overload def mul(a: _T_contra, b: SupportsRMul[_T_contra, _T_co], /) -> _T_co: ... -def matmul(a, b, /): ... +@overload +def matmul(a: _SupportsMatMul[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def matmul(a: _T_contra, b: _SupportsRMatMul[_T_contra, _T_co], /) -> _T_co: ... def neg(a: _SupportsNeg[_T_co], /) -> _T_co: ... -def or_(a, b, /): ... +@overload +def or_(a: _SupportsOr[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def or_(a: _T_contra, b: _SupportsROr[_T_contra, _T_co], /) -> _T_co: ... def pos(a: _SupportsPos[_T_co], /) -> _T_co: ... -def pow(a, b, /): ... -def rshift(a, b, /): ... +@overload +def pow(a: _SupportsPow[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def pow(a: _T_contra, b: _SupportsRPow[_T_contra, _T_co], /) -> _T_co: ... +@overload +def rshift(a: _SupportsRShift[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def rshift(a: _T_contra, b: _SupportsRRShift[_T_contra, _T_co], /) -> _T_co: ... @overload def sub(a: SupportsSub[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... @overload def sub(a: _T_contra, b: SupportsRSub[_T_contra, _T_co], /) -> _T_co: ... -def truediv(a, b, /): ... -def xor(a, b, /): ... +@overload +def truediv(a: _SupportsTrueDiv[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def truediv(a: _T_contra, b: _SupportsRTrueDiv[_T_contra, _T_co], /) -> _T_co: ... +@overload +def xor(a: _SupportsXOr[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def xor(a: _T_contra, b: _SupportsRXOr[_T_contra, _T_co], /) -> _T_co: ... 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: ... @@ -120,25 +262,98 @@ 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, 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, /): ... +@overload +def iadd(a: _SupportsIAdd[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def iadd(a: SupportsAdd[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def iadd(a: _T_contra, b: SupportsRAdd[_T_contra, _T_co], /) -> _T_co: ... +@overload +def iand(a: _SupportsIAnd[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def iand(a: _SupportsAnd[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def iand(a: _T_contra, b: _SupportsRAnd[_T_contra, _T_co], /) -> _T_co: ... +def iconcat(a: MutableSequence[_T], b: Sequence[_T], /) -> MutableSequence[_T]: ... # currently impossible to type more precisely +@overload +def ifloordiv(a: _SupportsIFloorDiv[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ifloordiv(a: _SupportsFloorDiv[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ifloordiv(a: _T_contra, b: _SupportsRFloorDiv[_T_contra, _T_co], /) -> _T_co: ... +@overload +def ilshift(a: _SupportsILShift[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ilshift(a: _SupportsLShift[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ilshift(a: _T_contra, b: _SupportsRLShift[_T_contra, _T_co], /) -> _T_co: ... +@overload +def imod(a: _SupportsIMod[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def imod(a: _SupportsMod[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def imod(a: _T_contra, b: _SupportsRMod[_T_contra, _T_co], /) -> _T_co: ... +@overload +def imul(a: _SupportsIMul[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def imul(a: SupportsMul[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def imul(a: _T_contra, b: SupportsRMul[_T_contra, _T_co], /) -> _T_co: ... +@overload +def imatmul(a: _SupportsIMatMul[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def imatmul(a: _SupportsMatMul[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def imatmul(a: _T_contra, b: _SupportsRMatMul[_T_contra, _T_co], /) -> _T_co: ... +@overload +def ior(a: _SupportsIOr[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ior(a: _SupportsOr[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ior(a: _T_contra, b: _SupportsROr[_T_contra, _T_co], /) -> _T_co: ... +@overload +def ipow(a: _SupportsIPow[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ipow(a: _SupportsPow[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ipow(a: _T_contra, b: _SupportsRPow[_T_contra, _T_co], /) -> _T_co: ... +@overload +def irshift(a: _SupportsIRShift[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def irshift(a: _SupportsRShift[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def irshift(a: _T_contra, b: _SupportsRRShift[_T_contra, _T_co], /) -> _T_co: ... +@overload +def isub(a: _SupportsISub[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def isub(a: SupportsSub[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def isub(a: _T_contra, b: SupportsRSub[_T_contra, _T_co], /) -> _T_co: ... +@overload +def itruediv(a: _SupportsITrueDiv[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def itruediv(a: _SupportsTrueDiv[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def itruediv(a: _T_contra, b: _SupportsRTrueDiv[_T_contra, _T_co], /) -> _T_co: ... +@overload +def ixor(a: _SupportsIXOr[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ixor(a: _SupportsXOr[_T_contra, _T_co], b: _T_contra, /) -> _T_co: ... +@overload +def ixor(a: _T_contra, b: _SupportsRXOr[_T_contra, _T_co], /) -> _T_co: ... if sys.version_info >= (3, 11): def call(obj: Callable[_P, _R], /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ... -def _compare_digest(a: AnyStr, b: AnyStr, /) -> bool: ... +if sys.version_info >= (3, 12): + from collections.abc import Buffer + + _B = TypeVar("_B", str, Buffer) + def _compare_digest(a: _B, b: _B, /) -> bool: ... + +else: + from typing import AnyStr + def _compare_digest(a: AnyStr, b: AnyStr, /) -> bool: ... if sys.version_info >= (3, 14): def is_none(a: object, /) -> TypeIs[None]: ...