From 042941c838542a023d6ba2dde477444c04207490 Mon Sep 17 00:00:00 2001 From: jan Date: Sun, 8 Mar 2026 15:05:08 -0700 Subject: [PATCH] [DeferredDict] improve handling of constants --- masque/utils/deferreddict.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/masque/utils/deferreddict.py b/masque/utils/deferreddict.py index aff3bcc..02c1a22 100644 --- a/masque/utils/deferreddict.py +++ b/masque/utils/deferreddict.py @@ -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 ''