[DeferredDict] improve handling of constants

This commit is contained in:
jan 2026-03-08 15:05:08 -07:00
commit 042941c838

View file

@ -25,9 +25,16 @@ class DeferredDict(dict, Generic[Key, Value]):
"""
def __init__(self, *args, **kwargs) -> None:
dict.__init__(self)
self.update(*args, **kwargs)
if args or kwargs:
self.update(*args, **kwargs)
def __setitem__(self, key: Key, value: Callable[[], Value]) -> None:
"""
Set a value, which must be a callable that returns the actual value.
The result of the callable is cached after the first access.
"""
if not callable(value):
raise TypeError(f"DeferredDict value must be callable, got {type(value)}")
cached_fn = lru_cache(maxsize=1)(value)
dict.__setitem__(self, key, cached_fn)
@ -35,8 +42,15 @@ class DeferredDict(dict, Generic[Key, Value]):
return dict.__getitem__(self, key)()
def update(self, *args, **kwargs) -> None:
"""
Update the DeferredDict. If a value is callable, it is used as a generator.
Otherwise, it is wrapped as a constant.
"""
for k, v in dict(*args, **kwargs).items():
self[k] = v
if callable(v):
self[k] = v
else:
self.set_const(k, v)
def __repr__(self) -> str:
return '<DeferredDict with keys ' + repr(set(self.keys())) + '>'