Skip to content

Binary Operations

In the Python docs, these are referred to as "arithmetic operations". But the operands aren't limited to numeric types, and because the operations aren't required to be commutative, might be non-deterministic, and could have side-effects. Classifying them "arithmetic" is, at the very least, a bit of a stretch.

operator operand
expression function type method type
_ + x do_add DoesAdd __add__ CanAdd[-T, +R = T]
CanAddSelf[-T]
CanAddSame[-T?, +R?]
_ - x do_sub DoesSub __sub__ CanSub[-T, +R = T]
CanSubSelf[-T]
CanSubSame[-T?, +R?]
_ * x do_mul DoesMul __mul__ CanMul[-T, +R = T]
CanMulSelf[-T]
CanMulSame[-T?, +R?]
_ @ x do_matmul DoesMatmul __matmul__ CanMatmul[-T, +R = T]
CanMatmulSelf[-T]
CanMatmulSame[-T?, +R?]
_ / x do_truediv DoesTruediv __truediv__ CanTruediv[-T, +R = T]
CanTruedivSelf[-T]
CanTruedivSame[-T?, +R?]
_ // x do_floordiv DoesFloordiv __floordiv__ CanFloordiv[-T, +R = T]
CanFloordivSelf[-T]
CanFloordivSame[-T?, +R?]
_ % x do_mod DoesMod __mod__ CanMod[-T, +R = T]
CanModSelf[-T]
CanModSame[-T?, +R?]
divmod(_, x) do_divmod DoesDivmod __divmod__ CanDivmod[-T, +R]
_ ** x
pow(_, x)
do_pow/2 DoesPow __pow__ CanPow2[-T, +R = T]
CanPowSelf[-T]
CanPowSame[-T?, +R?]
pow(_, x, m) do_pow/3 DoesPow __pow__ CanPow3[-T, -M, +R = int]
_ << x do_lshift DoesLshift __lshift__ CanLshift[-T, +R = T]
CanLshiftSelf[-T]
CanLshiftSame[-T?, +R?]
_ >> x do_rshift DoesRshift __rshift__ CanRshift[-T, +R = T]
CanRshiftSelf[-T]
CanRshiftSame[-T?, +R?]
_ & x do_and DoesAnd __and__ CanAnd[-T, +R = T]
CanAndSelf[-T]
CanAndSame[-T?, +R?]
_ ^ x do_xor DoesXor __xor__ CanXor[-T, +R = T]
CanXorSelf[-T]
CanXorSame[-T?, +R?]
_ | x do_or DoesOr __or__ CanOr[-T, +R = T]
CanOrSelf[-T]
CanOrSame[-T?, +R?]

Tip

Because pow() can take an optional third argument, optype provides separate interfaces for pow() with two and three arguments. Additionally, there is the overloaded intersection type type CanPow[-T, -M, +R, +RM] = CanPow2[T, R] & CanPow3[T, M, RM], as interface for types that can take an optional third argument.

Note

The Can*Self protocols method return typing.Self and optionally accept T and R. The Can*Same protocols also return Self, but instead accept Self | T, with T and R optional generic type parameters that default to typing.Never. To illustrate, CanAddSelf[T] implements __add__ as (self, rhs: T, /) -> Self, while CanAddSame[T, R] implements it as (self, rhs: Self | T, /) -> Self | R, and CanAddSame (without T and R) as (self, rhs: Self, /) -> Self.