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] |
_ ** xpow(_, 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.