Ran black code formatter on everything.
[python_utils.git] / deferred_operand.py
1 #!/usr/bin/env python3
2
3 from abc import ABC, abstractmethod
4 from typing import Any, Generic, TypeVar
5
6 # This module is commonly used by others in here and should avoid
7 # taking any unnecessary dependencies back on them.
8
9 T = TypeVar('T')
10
11
12 class DeferredOperand(ABC, Generic[T]):
13     """A wrapper around an operand whose value is deferred until it is
14     needed.  See subclass SmartFuture for an example usage.
15     """
16
17     @abstractmethod
18     def _resolve(self) -> T:
19         pass
20
21     @staticmethod
22     def resolve(x: Any) -> Any:
23         while isinstance(x, DeferredOperand):
24             x = x._resolve()
25         return x
26
27     def __lt__(self, other: Any) -> bool:
28         return DeferredOperand.resolve(self) < DeferredOperand.resolve(other)
29
30     def __le__(self, other: Any) -> bool:
31         return DeferredOperand.resolve(self) <= DeferredOperand.resolve(other)
32
33     def __eq__(self, other: Any) -> bool:
34         return DeferredOperand.resolve(self) == DeferredOperand.resolve(other)
35
36     def __ne__(self, other: Any) -> bool:
37         return DeferredOperand.resolve(self) != DeferredOperand.resolve(other)
38
39     def __gt__(self, other: Any) -> bool:
40         return DeferredOperand.resolve(self) > DeferredOperand.resolve(other)
41
42     def __ge__(self, other: Any) -> bool:
43         return DeferredOperand.resolve(self) >= DeferredOperand.resolve(other)
44
45     def __not__(self) -> bool:
46         return not DeferredOperand.resolve(self)
47
48     def bool(self) -> bool:
49         return DeferredOperand.resolve(self)
50
51     def __add__(self, other: Any) -> T:
52         return DeferredOperand.resolve(self) + DeferredOperand.resolve(other)
53
54     def __iadd__(self, other: Any) -> T:
55         return DeferredOperand.resolve(self) + DeferredOperand.resolve(other)
56
57     def __radd__(self, other: Any) -> T:
58         return DeferredOperand.resolve(self) + DeferredOperand.resolve(other)
59
60     def __sub__(self, other: Any) -> T:
61         return DeferredOperand.resolve(self) - DeferredOperand.resolve(other)
62
63     def __mul__(self, other: Any) -> T:
64         return DeferredOperand.resolve(self) * DeferredOperand.resolve(other)
65
66     def __pow__(self, other: Any) -> T:
67         return DeferredOperand.resolve(self) ** DeferredOperand.resolve(other)
68
69     def __truediv__(self, other: Any) -> Any:
70         return DeferredOperand.resolve(self) / DeferredOperand.resolve(other)
71
72     def __floordiv__(self, other: Any) -> T:
73         return DeferredOperand.resolve(self) // DeferredOperand.resolve(other)
74
75     def __contains__(self, other):
76         return DeferredOperand.resolve(other) in DeferredOperand.resolve(self)
77
78     def and_(self, other):
79         return DeferredOperand.resolve(self) & DeferredOperand.resolve(other)
80
81     def or_(self, other):
82         return DeferredOperand.resolve(self) & DeferredOperand.resolve(other)
83
84     def xor(self, other):
85         return DeferredOperand.resolve(self) & DeferredOperand.resolve(other)
86
87     def invert(self):
88         return ~(DeferredOperand.resolve(self))
89
90     def is_(self, other):
91         return DeferredOperand.resolve(self) is DeferredOperand.resolve(other)
92
93     def is_not(self, other):
94         return DeferredOperand.resolve(self) is not DeferredOperand.resolve(
95             other
96         )
97
98     def __abs__(self):
99         return abs(DeferredOperand.resolve(self))
100
101     def setitem(self, k, v):
102         DeferredOperand.resolve(self)[DeferredOperand.resolve(k)] = v
103
104     def delitem(self, k):
105         del DeferredOperand.resolve(self)[DeferredOperand.resolve(k)]
106
107     def getitem(self, k):
108         return DeferredOperand.resolve(self)[DeferredOperand.resolve(k)]
109
110     def lshift(self, other):
111         return DeferredOperand.resolve(self) << DeferredOperand.resolve(other)
112
113     def rshift(self, other):
114         return DeferredOperand.resolve(self) >> DeferredOperand.resolve(other)
115
116     def mod(self, other):
117         return DeferredOperand.resolve(self) % DeferredOperand.resolve(other)
118
119     def matmul(self, other):
120         return DeferredOperand.resolve(self) @ DeferredOperand.resolve(other)
121
122     def neg(self):
123         return -(DeferredOperand.resolve(self))
124
125     def pos(self):
126         return +(DeferredOperand.resolve(self))
127
128     def truth(self):
129         return DeferredOperand.resolve(self)
130
131     def __hash__(self):
132         return DeferredOperand.resolve(self).__hash__()
133
134     def __call__(self):
135         return DeferredOperand.resolve(self)()
136
137     def __iter__(self):
138         return DeferredOperand.resolve(self).__iter__()
139
140     def __repr__(self) -> str:
141         return DeferredOperand.resolve(self).__repr__()
142
143     def __bytes__(self) -> bytes:
144         return DeferredOperand.resolve(self).__bytes__()
145
146     def __int__(self) -> int:
147         return int(DeferredOperand.resolve(self))
148
149     def __float__(self) -> float:
150         return float(DeferredOperand.resolve(self))
151
152     def __getattr__(self, method_name):
153         def method(*args, **kwargs):
154             return getattr(DeferredOperand.resolve(self), method_name)(
155                 *args, **kwargs
156             )
157
158         return method