Coverage for src/zapy/templating/templating.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-10 19:35 +0000

1import ast 

2from typing import Any 

3 

4from jinja2 import Environment, StrictUndefined 

5 

6from .eval import eval_sync 

7 

8# internal use only 

9 

10 

11def evaluate(value: str, variables: dict | None = None) -> Any | str: 

12 if variables is None: 

13 variables = {} 

14 if _is_python(value): 

15 expression = _extract_expression(value) 

16 return eval_sync(expression, variables) 

17 else: 

18 return render(value, variables) 

19 

20 

21def render(source: str, variables: dict) -> str: 

22 jinja = Environment(undefined=StrictUndefined, autoescape=False) # noqa: S701 

23 template = jinja.from_string(source) 

24 rendered_template = template.render(**variables) 

25 return rendered_template 

26 

27 

28def _extract_expression(value: str) -> str: 

29 return value.removeprefix("{{").removesuffix("}}").strip() 

30 

31 

32def _is_python(value: str) -> bool: 

33 if not (value.startswith("{{") and value.endswith("}}")): 

34 return False 

35 expression = _extract_expression(value) 

36 if "{{" not in expression: 

37 return True 

38 try: 

39 ast.parse(expression) 

40 return True 

41 except SyntaxError: 

42 return False