3 # © Copyright 2021-2022, Scott Gasch
5 """This is a helper class that tries to define every __dunder__ method
6 so as to defer that evaluation of an object as long as possible. It
7 is used by smart_future.py as a base class.
11 from abc import ABC, abstractmethod
12 from typing import Any, Generic, TypeVar
14 # This module is commonly used by others in here and should avoid
15 # taking any unnecessary dependencies back on them.
20 class DeferredOperand(ABC, Generic[T]):
21 """A wrapper around an operand whose value is deferred until it is
22 needed (i.e. accessed). See the subclass :class:`SmartFuture` for
23 an example usage and/or a more useful patten.
27 def _resolve(self, timeout=None) -> T:
31 def resolve(x: Any) -> Any:
32 while isinstance(x, DeferredOperand):
36 def __lt__(self, other: Any) -> bool:
37 return DeferredOperand.resolve(self) < DeferredOperand.resolve(other)
39 def __le__(self, other: Any) -> bool:
40 return DeferredOperand.resolve(self) <= DeferredOperand.resolve(other)
42 def __eq__(self, other: Any) -> bool:
43 return DeferredOperand.resolve(self) == DeferredOperand.resolve(other)
45 def __ne__(self, other: Any) -> bool:
46 return DeferredOperand.resolve(self) != DeferredOperand.resolve(other)
48 def __gt__(self, other: Any) -> bool:
49 return DeferredOperand.resolve(self) > DeferredOperand.resolve(other)
51 def __ge__(self, other: Any) -> bool:
52 return DeferredOperand.resolve(self) >= DeferredOperand.resolve(other)
54 def __not__(self) -> bool:
55 return not DeferredOperand.resolve(self)
57 def bool(self) -> bool:
58 return DeferredOperand.resolve(self)
60 def __add__(self, other: Any) -> T:
61 return DeferredOperand.resolve(self) + DeferredOperand.resolve(other)
63 def __iadd__(self, other: Any) -> T:
64 return DeferredOperand.resolve(self) + DeferredOperand.resolve(other)
66 def __radd__(self, other: Any) -> T:
67 return DeferredOperand.resolve(self) + DeferredOperand.resolve(other)
69 def __sub__(self, other: Any) -> T:
70 return DeferredOperand.resolve(self) - DeferredOperand.resolve(other)
72 def __mul__(self, other: Any) -> T:
73 return DeferredOperand.resolve(self) * DeferredOperand.resolve(other)
75 def __pow__(self, other: Any) -> T:
76 return DeferredOperand.resolve(self) ** DeferredOperand.resolve(other)
78 def __truediv__(self, other: Any) -> Any:
79 return DeferredOperand.resolve(self) / DeferredOperand.resolve(other)
81 def __floordiv__(self, other: Any) -> T:
82 return DeferredOperand.resolve(self) // DeferredOperand.resolve(other)
84 def __contains__(self, other):
85 return DeferredOperand.resolve(other) in DeferredOperand.resolve(self)
87 def and_(self, other):
88 return DeferredOperand.resolve(self) & DeferredOperand.resolve(other)
91 return DeferredOperand.resolve(self) & DeferredOperand.resolve(other)
94 return DeferredOperand.resolve(self) & DeferredOperand.resolve(other)
97 return ~(DeferredOperand.resolve(self))
100 return DeferredOperand.resolve(self) is DeferredOperand.resolve(other)
102 def is_not(self, other):
103 return DeferredOperand.resolve(self) is not DeferredOperand.resolve(other)
106 return abs(DeferredOperand.resolve(self))
108 def setitem(self, k, v):
109 DeferredOperand.resolve(self)[DeferredOperand.resolve(k)] = v
111 def delitem(self, k):
112 del DeferredOperand.resolve(self)[DeferredOperand.resolve(k)]
114 def getitem(self, k):
115 return DeferredOperand.resolve(self)[DeferredOperand.resolve(k)]
117 def lshift(self, other):
118 return DeferredOperand.resolve(self) << DeferredOperand.resolve(other)
120 def rshift(self, other):
121 return DeferredOperand.resolve(self) >> DeferredOperand.resolve(other)
123 def mod(self, other):
124 return DeferredOperand.resolve(self) % DeferredOperand.resolve(other)
126 def matmul(self, other):
127 return DeferredOperand.resolve(self) @ DeferredOperand.resolve(other)
130 return -(DeferredOperand.resolve(self))
133 return +(DeferredOperand.resolve(self))
136 return DeferredOperand.resolve(self)
139 return DeferredOperand.resolve(self).__hash__()
142 return DeferredOperand.resolve(self)()
145 return DeferredOperand.resolve(self).__iter__()
147 def __repr__(self) -> str:
148 return DeferredOperand.resolve(self).__repr__()
150 def __bytes__(self) -> bytes:
151 return DeferredOperand.resolve(self).__bytes__()
153 def __int__(self) -> int:
154 return int(DeferredOperand.resolve(self))
156 def __float__(self) -> float:
157 return float(DeferredOperand.resolve(self))
159 def __getattr__(self, method_name):
160 def method(*args, **kwargs):
161 return getattr(DeferredOperand.resolve(self), method_name)(*args, **kwargs)