[DeferredDict] improve handling of constants
This commit is contained in:
parent
0f63acbad0
commit
042941c838
1 changed files with 16 additions and 2 deletions
|
|
@ -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())) + '>'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue