[DeferredDict] implement get/items/values for deferreddict
This commit is contained in:
parent
c2ef3e4217
commit
4ae8115139
2 changed files with 33 additions and 2 deletions
|
|
@ -2,7 +2,7 @@ import numpy
|
||||||
from numpy.testing import assert_equal, assert_allclose
|
from numpy.testing import assert_equal, assert_allclose
|
||||||
from numpy import pi
|
from numpy import pi
|
||||||
|
|
||||||
from ..utils import remove_duplicate_vertices, remove_colinear_vertices, poly_contains_points, rotation_matrix_2d, apply_transforms
|
from ..utils import remove_duplicate_vertices, remove_colinear_vertices, poly_contains_points, rotation_matrix_2d, apply_transforms, DeferredDict
|
||||||
|
|
||||||
|
|
||||||
def test_remove_duplicate_vertices() -> None:
|
def test_remove_duplicate_vertices() -> None:
|
||||||
|
|
@ -86,3 +86,21 @@ def test_apply_transforms_advanced() -> None:
|
||||||
# 2. rotate by outer rotation (pi/2): (10, 0) -> (0, 10)
|
# 2. rotate by outer rotation (pi/2): (10, 0) -> (0, 10)
|
||||||
# 3. add outer offset (0, 0) -> (0, 10)
|
# 3. add outer offset (0, 0) -> (0, 10)
|
||||||
assert_allclose(combined[0], [0, 10, pi / 2, 1, 1], atol=1e-10)
|
assert_allclose(combined[0], [0, 10, pi / 2, 1, 1], atol=1e-10)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deferred_dict_accessors_resolve_values_once() -> None:
|
||||||
|
calls = 0
|
||||||
|
|
||||||
|
def make_value() -> int:
|
||||||
|
nonlocal calls
|
||||||
|
calls += 1
|
||||||
|
return 7
|
||||||
|
|
||||||
|
deferred = DeferredDict[str, int]()
|
||||||
|
deferred["x"] = make_value
|
||||||
|
|
||||||
|
assert deferred.get("missing", 9) == 9
|
||||||
|
assert deferred.get("x") == 7
|
||||||
|
assert list(deferred.values()) == [7]
|
||||||
|
assert list(deferred.items()) == [("x", 7)]
|
||||||
|
assert calls == 1
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import TypeVar, Generic
|
from typing import TypeVar, Generic
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable, Iterator
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -41,6 +41,19 @@ class DeferredDict(dict, Generic[Key, Value]):
|
||||||
def __getitem__(self, key: Key) -> Value:
|
def __getitem__(self, key: Key) -> Value:
|
||||||
return dict.__getitem__(self, key)()
|
return dict.__getitem__(self, key)()
|
||||||
|
|
||||||
|
def get(self, key: Key, default: Value | None = None) -> Value | None:
|
||||||
|
if key not in self:
|
||||||
|
return default
|
||||||
|
return self[key]
|
||||||
|
|
||||||
|
def items(self) -> Iterator[tuple[Key, Value]]:
|
||||||
|
for key in self.keys():
|
||||||
|
yield key, self[key]
|
||||||
|
|
||||||
|
def values(self) -> Iterator[Value]:
|
||||||
|
for key in self.keys():
|
||||||
|
yield self[key]
|
||||||
|
|
||||||
def update(self, *args, **kwargs) -> None:
|
def update(self, *args, **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
Update the DeferredDict. If a value is callable, it is used as a generator.
|
Update the DeferredDict. If a value is callable, it is used as a generator.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue