Skip to content
Open
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8d34e56
Fully type `_operator` module
jonathandung Apr 5, 2026
12b636c
Fix pyright complaints
jonathandung Apr 5, 2026
fd6c0e3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 5, 2026
c94d18a
Merge branch 'main' into main
jonathandung Apr 6, 2026
7f824fe
Fix #15617
jonathandung Apr 6, 2026
a011515
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 6, 2026
71a0d0b
Fix false positive
jonathandung Apr 6, 2026
f26adc4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 6, 2026
d0836a5
Add noqas for now
jonathandung Apr 7, 2026
1473215
Merge branch 'python:main' into main
jonathandung Apr 7, 2026
80548ee
Add overloads
jonathandung Apr 8, 2026
5299bcd
Fix
jonathandung Apr 8, 2026
3f63e4d
Merge branch 'main' into main
AlexWaygood Apr 8, 2026
52f238e
Remove noqa's
jonathandung Apr 16, 2026
376e523
Merge branch 'python:main' into main
jonathandung Apr 16, 2026
d24b03c
commit
jonathandung Apr 23, 2026
c80a55c
undo
jonathandung Apr 23, 2026
c1beb06
Merge branch 'main' into main
jonathandung May 9, 2026
a0e0bb2
Merge branch 'main' into main
srittau May 11, 2026
14d56ef
Merge branch 'main' into main
srittau May 11, 2026
0cfd5ec
Merge branch 'main' into patch-6
jonathandung May 18, 2026
592d4fc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 18, 2026
6ecd830
Merge branch 'main' into patch-6
jonathandung May 19, 2026
d718168
Merge branch 'main' into patch-6
jonathandung May 20, 2026
383cdf2
Merge branch 'main' into patch-5
jonathandung Aug 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
325 changes: 278 additions & 47 deletions stdlib/_operator.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import sys
from _typeshed import (
ReadableBuffer,
SupportsAdd,
SupportsBool,
SupportsDunderGE,
SupportsDunderGT,
SupportsDunderLE,
SupportsDunderLT,
SupportsGetItem,
SupportsMod,
SupportsMul,
SupportsRAdd,
SupportsRMod,
SupportsRMul,
SupportsRSub,
SupportsSub,
Expand All @@ -24,39 +27,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: ...

@type_check_only
class _SupportsIAnd(Protocol[_T_contra, _T_co]):
def __iand__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsILShift(Protocol[_T_contra, _T_co]):
def __ilshift__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsIMod(Protocol[_T_contra, _T_co]):
def __imod__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsIMul(Protocol[_T_contra, _T_co]):
def __imul__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsIMatMul(Protocol[_T_contra, _T_co]):
def __imatmul__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsIOr(Protocol[_T_contra, _T_co]):
def __ior__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsIPow(Protocol[_T_contra, _T_co]):
def __ipow__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsIRShift(Protocol[_T_contra, _T_co]):
def __irshift__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsISub(Protocol[_T_contra, _T_co]):
def __isub__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsITrueDiv(Protocol[_T_contra, _T_co]):
def __itruediv__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsIXOr(Protocol[_T_contra, _T_co]):
def __ixor__(self, other: _T_contra) -> _T_co: ...

@type_check_only
class _SupportsIFloorDiv(Protocol[_T_contra, _T_co]):
def __ifloordiv__(self, other: _T_contra) -> _T_co: ...

# All four comparison functions must have the same signature, or we get false-positive errors
def lt(a: _SupportsComparison, b: _SupportsComparison, /) -> Any: ...
Expand All @@ -65,8 +180,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: ...
Expand All @@ -76,37 +191,74 @@ 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 mod(a: _T_contra, b: SupportsRMod[_T_contra, _T_co], /) -> _T_co: ...
def lshift(a: _T_contra, b: _SupportsRLShift[_T_contra, _T_co], /) -> _T_co: ...

@overload
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: ...
Expand All @@ -133,20 +285,99 @@ def setitem(a: MutableSequence[_T], b: slice[int | None], c: Sequence[_T], /) ->
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: ...
Expand Down