You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Recently found lazyasd and it seems like a great way to reduce startup times etc. But I found it problematic to use @lazyobject without type warnings.
Below is one approach to fix this. Curious if others find this is a good solution.
If so, this updated, typed version of @lazyobject may be useful.
fromtypingimportAny, Callable, Dict, Generic, Iterator, TypeVar, Mapping, castT=TypeVar("T")
classLazyObject(Generic[T]):
def__init__(self, load: Callable[[], T], ctx: Mapping[str, T], name: str):
""" Lazily loads an object via the load function the first time an attribute is accessed. Once loaded it will replace itself in the provided context (typically the globals of the call site) with the given name. Parameters ---------- load : Callable[[], T] A loader function that performs the actual object construction. ctx : Mapping[str, T] Context to replace the LazyObject instance in with the object returned by load(). name : str Name in the context to give the loaded object. This *should* be the name on the LHS of the assignment. """self._lasdo: Dict[str, Any] = {
"loaded": False,
"load": load,
"ctx": ctx,
"name": name,
}
def_lazy_obj(self) ->T:
d=self._lasdoifd["loaded"]:
returnd["obj"]
try:
obj=d["load"]()
d["ctx"][d["name"]] =d["obj"] =objd["loaded"] =TruereturnobjexceptExceptionase:
raiseRuntimeError(f"Error loading object: {e}")
def__getattribute__(self, name: str) ->Any:
ifnamein {"_lasdo", "_lazy_obj"}:
returnsuper().__getattribute__(name)
obj=self._lazy_obj()
returngetattr(obj, name)
def__bool__(self) ->bool:
returnbool(self._lazy_obj())
def__iter__(self) ->Iterator:
returniter(self._lazy_obj()) # type: ignoredef__getitem__(self, item: Any) ->Any:
returnself._lazy_obj()[item] # type: ignoredef__setitem__(self, key: Any, value: Any) ->None:
self._lazy_obj()[key] =value# type: ignoredef__delitem__(self, item: Any) ->None:
delself._lazy_obj()[item] # type: ignoredef__call__(self, *args: Any, **kwargs: Any) ->Any:
returnself._lazy_obj()(*args, **kwargs) # type: ignoredef__lt__(self, other: Any) ->bool:
returnself._lazy_obj() <otherdef__le__(self, other: Any) ->bool:
returnself._lazy_obj() <=otherdef__eq__(self, other: Any) ->bool:
returnself._lazy_obj() ==otherdef__ne__(self, other: Any) ->bool:
returnself._lazy_obj() !=otherdef__gt__(self, other: Any) ->bool:
returnself._lazy_obj() >otherdef__ge__(self, other: Any) ->bool:
returnself._lazy_obj() >=otherdef__hash__(self) ->int:
returnhash(self._lazy_obj())
def__or__(self, other: Any) ->Any:
returnself._lazy_obj() |otherdef__str__(self) ->str:
returnstr(self._lazy_obj())
def__repr__(self) ->str:
returnrepr(self._lazy_obj())
deflazyobject(f: Callable[[], T]) ->T:
""" Decorator for constructing lazy objects from a function. For simplicity, we tell a white lie to the type checker that this is actually of type T. """returncast(T, LazyObject(f, f.__globals__, f.__name__))
The text was updated successfully, but these errors were encountered:
Recently found lazyasd and it seems like a great way to reduce startup times etc. But I found it problematic to use @lazyobject without type warnings.
Below is one approach to fix this. Curious if others find this is a good solution.
If so, this updated, typed version of @lazyobject may be useful.
The text was updated successfully, but these errors were encountered: