Source code for jinjyaml.constructor

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Union

from yaml.nodes import Node, ScalarNode

from .data import Data

if TYPE_CHECKING:  # pragma: no cover
    from yaml.cyaml import _CLoader
    from yaml.loader import _Loader


__all__ = ["Constructor"]


[docs] class Constructor: """Constructor class for :class:`jinja2.Template` YAML tags. When parsing a YAML string, this class constructs template tags into :class:`.Data` objects. To add the constructor to a PyYAML loader, use the following code:: import yaml import jinjyaml as jy ctor = jy.Constructor() # Note: Tag names start with "!" # Add to default loader yaml.add_constructor("!j2", ctor) # or: Add to CLoader yaml.add_constructor("!j2", ctor, yaml.CLoader) # or: Add to SafeLoader yaml.add_constructor("!j2", ctor, yaml.SafeLoader) # or: Add to other loaders... Attention: - Custom YAML tags must start with ``"!"``. When invoking ``yaml.add_constructor``, the ``tag`` parameter **must** include a single leading ``"!"``. - The content of the tag **must** be text. """ def __call__(self, loader: Union[_Loader, _CLoader], node: Node) -> Union[Data, Any]: if not isinstance(node, ScalarNode): raise TypeError(f"`{self.__class__.__name__}` expects `{ScalarNode.__name__}`, but actual `{type(node).__name__}`") source = loader.construct_scalar(node) if not isinstance(source, str): # pragma: no cover raise TypeError(f"`{self.__class__.__name__}` expects `str`, but actual `{type(source).__name__}`") return Data(source)