diff --git a/emrichen/tags/lookup.py b/emrichen/tags/lookup.py index 78610db..cab262a 100644 --- a/emrichen/tags/lookup.py +++ b/emrichen/tags/lookup.py @@ -7,13 +7,31 @@ from .base import BaseTag +class EnrichingProxy: + """ + Eager JSONPath lookups and Emrichen's lazy evaluation don't always mix well. + Deep nesting with !Var etc. may cause a situation where we try to !Lookup or + !Format on a structure that is not yet enriched. + + This tries to fix that by enriching property access. + + https://github.com/con2/emrichen/issues/15 + """ + def __init__(self, obj, context): + self.obj = obj + self.context = context + + def __getitem__(self, index): + return self.context.enrich(self.obj[index]) + + @lru_cache() def parse_jsonpath(expr: str): return jsonpath_rw.parse(expr) def find_jsonpath_in_context(jsonpath_str: str, context: Context) -> List[jsonpath_rw.DatumInContext]: - return parse_jsonpath(jsonpath_str).find(context) + return parse_jsonpath(jsonpath_str).find(EnrichingProxy(context, context)) class Lookup(BaseTag): diff --git a/tests/test_lookup.py b/tests/test_lookup.py index ca8dd01..875a504 100644 --- a/tests/test_lookup.py +++ b/tests/test_lookup.py @@ -68,7 +68,6 @@ def test_lookup_no_match(): assert 'no matches for' in str(ei.value) -@pytest.mark.xfail def test_late_enrich(): template = Template.parse(''' !Defaults @@ -98,3 +97,17 @@ def test_lookup_enrich(): template: !Var item ''') assert template.enrich({}) == [{'should_contain_5': [5]}] + + +@pytest.mark.xfail +def test_recursive_data_structure(): + template = Template.parse(''' +!Defaults +x: + y: 5 + x: !Var x +--- +five: !Lookup x.y +also_five: !Lookup x.x.x.x.x.y +''') + assert template.enrich({}) == [{'five': 5, 'also_five': 5}] \ No newline at end of file