mirror of https://github.com/ansible/ansible.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.6 KiB
Python
108 lines
3.6 KiB
Python
from __future__ import annotations
|
|
|
|
import dataclasses
|
|
import typing as t
|
|
|
|
from ansible.module_utils._internal import _ambient_context, _datatag
|
|
|
|
if t.TYPE_CHECKING:
|
|
from ._engine import TemplateEngine, TemplateOptions
|
|
|
|
|
|
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
|
|
class LazyOptions:
|
|
"""Templating options that apply to lazy containers, which are inherited by descendent lazy containers."""
|
|
|
|
DEFAULT: t.ClassVar[t.Self]
|
|
"""A shared instance with the default options to minimize instance creation for arg defaults."""
|
|
SKIP_TEMPLATES: t.ClassVar[t.Self]
|
|
"""A shared instance with only `template=False` set to minimize instance creation for arg defaults."""
|
|
SKIP_TEMPLATES_AND_ACCESS: t.ClassVar[t.Self]
|
|
"""A shared instance with both `template=False` and `access=False` set to minimize instance creation for arg defaults."""
|
|
|
|
template: bool = True
|
|
"""Enable/disable templating."""
|
|
|
|
access: bool = True
|
|
"""Enable/disables access calls."""
|
|
|
|
unmask_type_names: frozenset[str] = frozenset()
|
|
"""Disables template transformations for the provided type names."""
|
|
|
|
|
|
LazyOptions.DEFAULT = LazyOptions()
|
|
LazyOptions.SKIP_TEMPLATES = LazyOptions(template=False)
|
|
LazyOptions.SKIP_TEMPLATES_AND_ACCESS = LazyOptions(template=False, access=False)
|
|
|
|
|
|
class TemplateContext(_ambient_context.AmbientContextBase):
|
|
def __init__(
|
|
self,
|
|
*,
|
|
template_value: t.Any,
|
|
templar: TemplateEngine,
|
|
options: TemplateOptions,
|
|
stop_on_template: bool = False,
|
|
_render_jinja_const_template: bool = False,
|
|
):
|
|
self._template_value = template_value
|
|
self._templar = templar
|
|
self._options = options
|
|
self._stop_on_template = stop_on_template
|
|
self._parent_ctx = TemplateContext.current(optional=True)
|
|
self._render_jinja_const_template = _render_jinja_const_template
|
|
|
|
@property
|
|
def is_top_level(self) -> bool:
|
|
return not self._parent_ctx
|
|
|
|
@property
|
|
def template_value(self) -> t.Any:
|
|
return self._template_value
|
|
|
|
@property
|
|
def templar(self) -> TemplateEngine:
|
|
return self._templar
|
|
|
|
@property
|
|
def options(self) -> TemplateOptions:
|
|
return self._options
|
|
|
|
@property
|
|
def stop_on_template(self) -> bool:
|
|
return self._stop_on_template
|
|
|
|
|
|
class _OmitType:
|
|
"""
|
|
A placeholder singleton used to dynamically omit items from a dict/list/tuple/set when the value is `Omit`.
|
|
|
|
The `Omit` singleton is accessible from all Ansible templating contexts via the Jinja global name `omit`.
|
|
The `Omit` placeholder value will be visible to Jinja plugins during templating.
|
|
Jinja plugins requiring omit behavior are responsible for handling encountered `Omit` values.
|
|
`Omit` values remaining in template results will be automatically dropped during template finalization.
|
|
When a finalized template renders to a scalar `Omit`, `AnsibleValueOmittedError` will be raised.
|
|
Passing a value other than `Omit` for `value_for_omit` to the `template` call allows that value to be substituted instead of raising.
|
|
"""
|
|
|
|
__slots__ = ()
|
|
|
|
def __new__(cls):
|
|
return Omit
|
|
|
|
def __repr__(self):
|
|
return "<<Omit>>"
|
|
|
|
|
|
Omit = object.__new__(_OmitType)
|
|
|
|
_datatag._untaggable_types.add(_OmitType)
|
|
|
|
|
|
# DTFIX0: review these type sets to ensure they're not overly permissive/dynamic
|
|
IGNORE_SCALAR_VAR_TYPES = {value for value in _datatag._ANSIBLE_ALLOWED_SCALAR_VAR_TYPES if not issubclass(value, str)}
|
|
|
|
PASS_THROUGH_SCALAR_VAR_TYPES = _datatag._ANSIBLE_ALLOWED_SCALAR_VAR_TYPES | {
|
|
_OmitType, # allow pass through of omit for later handling after top-level finalize completes
|
|
}
|