blob: 07ec5a24fa77c1bc4838d0c459e44198dffbafa6 [file] [log] [blame]
"""Information about Python operators"""
from __future__ import annotations
from typing import Final
# Map from binary operator id to related method name (in Python 3).
op_methods: Final = {
"+": "__add__",
"-": "__sub__",
"*": "__mul__",
"/": "__truediv__",
"%": "__mod__",
"divmod": "__divmod__",
"//": "__floordiv__",
"**": "__pow__",
"@": "__matmul__",
"&": "__and__",
"|": "__or__",
"^": "__xor__",
"<<": "__lshift__",
">>": "__rshift__",
"==": "__eq__",
"!=": "__ne__",
"<": "__lt__",
">=": "__ge__",
">": "__gt__",
"<=": "__le__",
"in": "__contains__",
}
op_methods_to_symbols: Final = {v: k for (k, v) in op_methods.items()}
ops_falling_back_to_cmp: Final = {"__ne__", "__eq__", "__lt__", "__le__", "__gt__", "__ge__"}
ops_with_inplace_method: Final = {
"+",
"-",
"*",
"/",
"%",
"//",
"**",
"@",
"&",
"|",
"^",
"<<",
">>",
}
inplace_operator_methods: Final = {"__i" + op_methods[op][2:] for op in ops_with_inplace_method}
reverse_op_methods: Final = {
"__add__": "__radd__",
"__sub__": "__rsub__",
"__mul__": "__rmul__",
"__truediv__": "__rtruediv__",
"__mod__": "__rmod__",
"__divmod__": "__rdivmod__",
"__floordiv__": "__rfloordiv__",
"__pow__": "__rpow__",
"__matmul__": "__rmatmul__",
"__and__": "__rand__",
"__or__": "__ror__",
"__xor__": "__rxor__",
"__lshift__": "__rlshift__",
"__rshift__": "__rrshift__",
"__eq__": "__eq__",
"__ne__": "__ne__",
"__lt__": "__gt__",
"__ge__": "__le__",
"__gt__": "__lt__",
"__le__": "__ge__",
}
reverse_op_method_names: Final = set(reverse_op_methods.values())
# Suppose we have some class A. When we do A() + A(), Python will only check
# the output of A().__add__(A()) and skip calling the __radd__ method entirely.
# This shortcut is used only for the following methods:
op_methods_that_shortcut: Final = {
"__add__",
"__sub__",
"__mul__",
"__truediv__",
"__mod__",
"__divmod__",
"__floordiv__",
"__pow__",
"__matmul__",
"__and__",
"__or__",
"__xor__",
"__lshift__",
"__rshift__",
}
normal_from_reverse_op: Final = {m: n for n, m in reverse_op_methods.items()}
reverse_op_method_set: Final = set(reverse_op_methods.values())
unary_op_methods: Final = {"-": "__neg__", "+": "__pos__", "~": "__invert__"}