# -*- coding: utf-8 -*-
"""
The AS3Declaration module. Represents an AS3 Declaration as a python class.
"""
# pylint: disable=C0330 # Wrong hanging indentation before block
# pylint: disable=C0301 # Line too long
import json
from typing import Dict, Optional
from jinja2 import (
ChoiceLoader,
DictLoader,
Environment,
FileSystemLoader,
StrictUndefined,
)
from jinja2.exceptions import TemplateSyntaxError, UndefinedError
from .exceptions import AS3JSONDecodeError, AS3TemplateSyntaxError, AS3UndefinedError
from .jinja2 import J2Ninja
__all__ = ["AS3Declaration"]
[docs]class AS3Declaration:
"""Creates an AS3Declaration instance representing the AS3 declaration.
The AS3 declaration is created using the given template configuration, which can be either a dict or list of dicts.
If a list is provided, the member dicts will be merged using :py:meth:`_dict_deep_update`.
Optionally a jinja2 declaration_template can be provided, otherwise it is read from the configuration.
The template file reference is expected to be at `as3ninja.declaration_template` within the configuration.
An explicitly specified declaration_template takes precedence over any included template.
:param template_configuration: AS3 Template Configuration as ``dict`` or ``list``
:param declaration_template: Optional Declaration Template as ``str`` (Default value = ````)
:param jinja2_searchpath: The jinja2 search path for the FileSystemLoader. Important for jinja2 includes. (Default value = ``"."``)
"""
def __init__(
self,
template_configuration: Dict,
declaration_template: Optional[str] = None,
jinja2_searchpath: str = ".",
):
self._template_configuration = template_configuration
self._declaration_template = declaration_template or ""
self._jinja2_searchpath = jinja2_searchpath
if not self._declaration_template:
try:
declaration_template_file = self._template_configuration["as3ninja"][
"declaration_template"
]
with open(
f"{self._jinja2_searchpath}/{declaration_template_file}", "r"
) as declaration_template_file_fh:
self._declaration_template = declaration_template_file_fh.read()
except (KeyError, TypeError) as exc:
raise KeyError(
f"as3ninja.declaration_template not valid or missing in template_configuration: {exc}"
)
self._transform()
[docs] def dict(self) -> dict:
"""Returns the AS3 Declaration."""
return self._declaration
[docs] def json(self) -> str:
"""Returns the AS3 Declaration as JSON."""
return self._declaration_json
@property
def declaration_template(self) -> str:
"""Property contains the declaration template loaded or provided during instantiation"""
return self._declaration_template
[docs] def _jinja2_render(self) -> str:
"""Renders the declaration using jinja2.
Raises relevant exceptions which need to be handled by the caller.
"""
env = Environment( # nosec (bandit: autoescaping is not helpful for as3ninja's use-case)
loader=ChoiceLoader(
[
DictLoader({"template": self.declaration_template}),
FileSystemLoader(searchpath=self._jinja2_searchpath),
]
),
trim_blocks=False,
lstrip_blocks=False,
keep_trailing_newline=True,
undefined=StrictUndefined,
autoescape=False,
)
env.globals["jinja2_searchpath"] = self._jinja2_searchpath + "/"
env.globals["ninja"] = self._template_configuration
env.globals.update(J2Ninja.functions)
env.filters.update(J2Ninja.filters)
env.tests.update(J2Ninja.tests)
return env.get_template("template").render()