operators.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """Information about Python operators"""
  2. from __future__ import annotations
  3. from typing import Final
  4. # Map from binary operator id to related method name (in Python 3).
  5. op_methods: Final = {
  6. "+": "__add__",
  7. "-": "__sub__",
  8. "*": "__mul__",
  9. "/": "__truediv__",
  10. "%": "__mod__",
  11. "divmod": "__divmod__",
  12. "//": "__floordiv__",
  13. "**": "__pow__",
  14. "@": "__matmul__",
  15. "&": "__and__",
  16. "|": "__or__",
  17. "^": "__xor__",
  18. "<<": "__lshift__",
  19. ">>": "__rshift__",
  20. "==": "__eq__",
  21. "!=": "__ne__",
  22. "<": "__lt__",
  23. ">=": "__ge__",
  24. ">": "__gt__",
  25. "<=": "__le__",
  26. "in": "__contains__",
  27. }
  28. op_methods_to_symbols: Final = {v: k for (k, v) in op_methods.items()}
  29. ops_falling_back_to_cmp: Final = {"__ne__", "__eq__", "__lt__", "__le__", "__gt__", "__ge__"}
  30. ops_with_inplace_method: Final = {
  31. "+",
  32. "-",
  33. "*",
  34. "/",
  35. "%",
  36. "//",
  37. "**",
  38. "@",
  39. "&",
  40. "|",
  41. "^",
  42. "<<",
  43. ">>",
  44. }
  45. inplace_operator_methods: Final = {"__i" + op_methods[op][2:] for op in ops_with_inplace_method}
  46. reverse_op_methods: Final = {
  47. "__add__": "__radd__",
  48. "__sub__": "__rsub__",
  49. "__mul__": "__rmul__",
  50. "__truediv__": "__rtruediv__",
  51. "__mod__": "__rmod__",
  52. "__divmod__": "__rdivmod__",
  53. "__floordiv__": "__rfloordiv__",
  54. "__pow__": "__rpow__",
  55. "__matmul__": "__rmatmul__",
  56. "__and__": "__rand__",
  57. "__or__": "__ror__",
  58. "__xor__": "__rxor__",
  59. "__lshift__": "__rlshift__",
  60. "__rshift__": "__rrshift__",
  61. "__eq__": "__eq__",
  62. "__ne__": "__ne__",
  63. "__lt__": "__gt__",
  64. "__ge__": "__le__",
  65. "__gt__": "__lt__",
  66. "__le__": "__ge__",
  67. }
  68. reverse_op_method_names: Final = set(reverse_op_methods.values())
  69. # Suppose we have some class A. When we do A() + A(), Python will only check
  70. # the output of A().__add__(A()) and skip calling the __radd__ method entirely.
  71. # This shortcut is used only for the following methods:
  72. op_methods_that_shortcut: Final = {
  73. "__add__",
  74. "__sub__",
  75. "__mul__",
  76. "__truediv__",
  77. "__mod__",
  78. "__divmod__",
  79. "__floordiv__",
  80. "__pow__",
  81. "__matmul__",
  82. "__and__",
  83. "__or__",
  84. "__xor__",
  85. "__lshift__",
  86. "__rshift__",
  87. }
  88. normal_from_reverse_op: Final = {m: n for n, m in reverse_op_methods.items()}
  89. reverse_op_method_set: Final = set(reverse_op_methods.values())
  90. unary_op_methods: Final = {"-": "__neg__", "+": "__pos__", "~": "__invert__"}