Atlas-Install/source/safe_eval/multiple_safe_eval.py

49 lines
1.9 KiB
Python

from typing import TYPE_CHECKING, Iterable, Callable
from source.safe_eval.safe_eval import safe_eval
from source.safe_eval import better_safe_eval_error
if TYPE_CHECKING:
from source import TemplateMultipleSafeEval, TemplateSafeEval, Env
TOKEN_START, TOKEN_END = "{{", "}}"
def multiple_safe_eval(template: "TemplateMultipleSafeEval", env: "Env" = None,
macros: dict[str, "TemplateSafeEval"] = None, args: Iterable[str] = None) -> Callable:
"""
Similar to safe_eval, but expression need to be enclosed between "{{" and "}}".
Example : "{{ track.author }} is the track creator !"
"""
lambda_templates: list[str | Callable] = []
while len(template) > 0:
token_start: int = template.find(TOKEN_START) # the position of the "{{"
part_template_start: int = token_start + len(TOKEN_START) # the position just after the start token
part_template_end: int = template.find(TOKEN_END) # the position before the end token
token_end: int = part_template_end + len(TOKEN_END) # the end position of the "}}"
# if there is no more template, add all the template into the lambda
if token_start < 0 or part_template_end < 0:
lambda_templates.append(template)
template = ""
# if there is still a template part, add the remaining text, then add the lambda template between the tokens.
else:
lambda_templates.append(template[:token_start])
lambda_templates.append(safe_eval(
template=template[part_template_start:part_template_end].strip(),
env=env,
macros=macros,
args=args,
))
template = template[token_end:]
return better_safe_eval_error(lambda *args, **kwargs: "".join([
str(part(*args, **kwargs)) if callable(part) else part
for part in lambda_templates
]), template=template)