From 12d50d1e3bdee7e60937cb19dfd23f5badbfcb8d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 12 Aug 2020 08:43:35 +0200 Subject: items: Add recursive ItemMapper substitution --- rtemsspec/items.py | 19 +++++++++++++++++-- rtemsspec/tests/spec-item-cache/d/c.yml | 1 + rtemsspec/tests/spec-item-cache/p.yml | 6 ++++++ rtemsspec/tests/test_items_itemcache.py | 2 ++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/rtemsspec/items.py b/rtemsspec/items.py index fa64f009..f44728cd 100644 --- a/rtemsspec/items.py +++ b/rtemsspec/items.py @@ -314,8 +314,9 @@ class ItemTemplate(string.Template): class ItemMapper(Mapping[str, object]): """ Maps identifiers to items and attribute values. """ - def __init__(self, item: Item): + def __init__(self, item: Item, recursive: bool = False): self._item = item + self._recursive = recursive self._prefix = [""] self._get_value = {} # type: Dict[str, ItemGetValue] @@ -373,8 +374,22 @@ class ItemMapper(Mapping[str, object]): value = getattr(self, func)(value) return item, key_path, value + @contextmanager + def _item_and_prefix(self, item: Item, prefix: str) -> Iterator[None]: + item_2 = self._item + prefix_2 = self._prefix + self._item = item + self._prefix = [prefix] + yield + self._item = item_2 + self._prefix = prefix_2 + def __getitem__(self, identifier): - return self.map(identifier)[2] + item, key_path, value = self.map(identifier) + if self._recursive: + with self._item_and_prefix(item, os.path.dirname(key_path)): + return self.substitute(value) + return value def __iter__(self): raise StopIteration diff --git a/rtemsspec/tests/spec-item-cache/d/c.yml b/rtemsspec/tests/spec-item-cache/d/c.yml index f901443f..4b9febc6 100644 --- a/rtemsspec/tests/spec-item-cache/d/c.yml +++ b/rtemsspec/tests/spec-item-cache/d/c.yml @@ -11,3 +11,4 @@ links: - role: null uid: ../p v: c +r6: ${../p:/r7} diff --git a/rtemsspec/tests/spec-item-cache/p.yml b/rtemsspec/tests/spec-item-cache/p.yml index 4c3a2964..409b1695 100644 --- a/rtemsspec/tests/spec-item-cache/p.yml +++ b/rtemsspec/tests/spec-item-cache/p.yml @@ -2,3 +2,9 @@ links: [] v: p x: y: z +r1: + r2: + r3: ${.:../r4} + r4: ${.:../r5} +r5: ${/d/c:/r6} +r7: foobar diff --git a/rtemsspec/tests/test_items_itemcache.py b/rtemsspec/tests/test_items_itemcache.py index 23237603..b8507fc4 100644 --- a/rtemsspec/tests/test_items_itemcache.py +++ b/rtemsspec/tests/test_items_itemcache.py @@ -128,6 +128,8 @@ def test_item_mapper(tmpdir): pass with pytest.raises(AttributeError): len(mapper) + recursive_mapper = ItemMapper(item, recursive=True) + assert recursive_mapper.substitute("${.:/r1/r2/r3}") == "foobar" def test_empty_item_mapper(): -- cgit v1.2.3