Skip to content

Commit

Permalink
support.lazy: make __bool__ work.
Browse files Browse the repository at this point in the history
`if lazy_obj:` didn't work with e.g. `str` because `str.__bool__()`
does not exist.
  • Loading branch information
whitequark committed Jul 26, 2024
1 parent 7e26041 commit 346e5c4
Showing 1 changed file with 33 additions and 21 deletions.
54 changes: 33 additions & 21 deletions software/glasgow/support/lazy.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,35 +33,47 @@ def __delattr__(self, attr):
self._force_()
delattr(self._object_, attr)

def __bool__(self):
self._force_()
if self._object_:
return True
else:
return False

def __repr__(self):
if self._thunk_:
rep = repr(self._thunk_)
else:
rep = repr(self._object_)
return f"<lazy {rep}>"

@classmethod
def _define_special_(cls, name):

def define_specials():
def define_special(name):
def forward(self, *args, **kwargs):
self._force_()
return getattr(self._object_, name)(*args, **kwargs)
forward.__name__ = name
setattr(cls, name, forward)

# See https://docs.python.org/3/reference/datamodel.html#special-lookup
_specials = [
"__str__", "__bytes__", "__format__", "__lt__", "__le__", "__eq__", "__ne__", "__gt__",
"__ge__", "__hash__", "__bool__", "__dir__", "__call__", "__len__", "__length_hint__",
"__getitem__", "__setitem__", "__delitem__", "__iter__", "__reversed__", "__contains__",
"__add__", "__sub__", "__mul__", "__matmul__", "__truediv__", "__floordiv__", "__mod__",
"__divmod__", "__pow__", "__lshift__", "__rshift__", "__and__", "__xor__", "__or__",
"__radd__", "__rsub__", "__rmul__", "__rmatmul__", "__rtruediv__", "__rfloordiv__", "__rmod__",
"__rdivmod__", "__rpow__", "__rlshift__", "__rrshift__", "__rand__", "__rxor__", "__ror__",
"__iadd__", "__isub__", "__imul__", "__imatmul__", "__itruediv__", "__ifloordiv__", "__imod__",
"__ipow__", "__ilshift__", "__irshift__", "__iand__", "__ixor__", "__ior__", "__neg__",
"__pos__", "__abs__", "__invert__", "__complex__", "__int__", "__float__", "__index__",
"__round__", "__trunc__", "__floor__", "__ceil__", "__enter__", "__exit__", "__await__",
"__aiter__", "__anext__", "__aenter__", "__aexit__"
]
for special in _specials:
lazy._define_special_(special)
setattr(lazy, name, forward)

# See https://docs.python.org/3/reference/datamodel.html#special-lookup
# Note that the loop body has to be in a separate function because of local variable scoping.
for name in [
"__str__", "__bytes__", "__format__", "__lt__", "__le__", "__eq__", "__ne__", "__gt__",
"__ge__", "__hash__", "__dir__", "__call__", "__len__", "__length_hint__",
"__getitem__", "__setitem__", "__delitem__", "__iter__", "__reversed__", "__contains__",
"__add__", "__sub__", "__mul__", "__matmul__", "__truediv__", "__floordiv__", "__mod__",
"__divmod__", "__pow__", "__lshift__", "__rshift__", "__and__", "__xor__", "__or__",
"__radd__", "__rsub__", "__rmul__", "__rmatmul__", "__rtruediv__", "__rfloordiv__", "__rmod__",
"__rdivmod__", "__rpow__", "__rlshift__", "__rrshift__", "__rand__", "__rxor__", "__ror__",
"__iadd__", "__isub__", "__imul__", "__imatmul__", "__itruediv__", "__ifloordiv__", "__imod__",
"__ipow__", "__ilshift__", "__irshift__", "__iand__", "__ixor__", "__ior__", "__neg__",
"__pos__", "__abs__", "__invert__", "__complex__", "__int__", "__float__", "__index__",
"__round__", "__trunc__", "__floor__", "__ceil__", "__enter__", "__exit__", "__await__",
"__aiter__", "__anext__", "__aenter__", "__aexit__"
]:
define_special(name)


define_specials()
del define_specials

0 comments on commit 346e5c4

Please sign in to comment.