API

ENYAML is Evaluation Notation YAML.

It is implemented on top of the PyYAML module, using the TemplateLoader and TemplateDumper classes, and a handful of Node subclasses.

High-Level API

The ENYAML high-level API is the same as that of the yaml module. The top-level functions are wrappers around the functions from that module, which pass TemplateLoader and TemplateDumper as the default Loader and Dumper arguments. A subclass of yaml.YAMLObject is also provided for convenience.

Additionally, two new high-level functions are provided for rendering ENYAML templates.

render(stream, ctx, Loader=<class 'enyaml.loader.TemplateLoader'>)

Load and render a single-document template.

Parameters:
  • stream (file-like) – The stream to read the template from.

  • ctx (Context) – A Context instance.

  • Loader – The loader class to instantiate.

Returns:

The rendered data.

Note

The input YAML can have multiple documents, as long as only the last one produces output when rendered. For example, the following counts as a single-document template:

---
!set
name: Guido
---
salutation: !$f "Hello, {name}"
render_all(stream, ctx, Loader=<class 'enyaml.loader.TemplateLoader'>)

Load and render a stream of template documents.

Parameters:
  • stream (file-like) – The stream to read the templates from.

  • ctx (Context) – A Context instance.

  • Loader – The loader class to instantiate.

Returns:

An iterable containing rendered data.

Only documents which produce output when rendered will be included in the result.

Context

class Context(*maps)

Bases: ChainMap

Context objects behave like a mapping, with the added benefit of multiple “levels” of scope. Modifications to the Context at a given scope will be discarded when the scope is exited. For example:

>>> c = Context()
>>> c['foo'] = 1
>>> with c.push():
...     c['foo'] = 2
...     c['bar'] = 3
...     dict(c)
{'foo': 2, 'bar': 3}
>>> dict(c)
{'foo': 1}
push(dct=None, pos=0)

Push a mapping onto the Context as a new scope.

Parameters:
  • dct (mapping, optional) – A mapping object to push onto the Context. If not specified or None, a new dict will be created.

  • pos (int, optional) – The position in the stack to insert the mapping. The inner-most scope is 0, which is the default.

Returns:

A context manager which will remove the scope from the Context upon exit.

Examples:

>>> c = Context({'foo': 1})
>>> with c.push():
...     c['foo'] = 2
...     dict(c)
{'foo': 2}
>>> dict(c)
{'foo': 1}
>>> with c.push({'bar': 1}):
...     dict(c)
{'foo': 1, 'bar': 1}
>>> dict(c)
{'foo': 1}
>>> with c.push():
...     with c.push({'baz': 1}, 1):
...         c['bar'] = c['baz']
...     dict(c)
{'foo': 1, 'bar': 1}

Loader

class TemplateLoader(stream)

Bases: SafeLoader

Loads and renders ENYAML templates.

Parameters:

stream (file-like) – The stream to read the templates from.

render_data(ctx)

Renders the next document in the stream.

Parameters:

ctx (Context) – The Context with which to render.

Returns:

Rendered result.

render_single_data(ctx)

Renders a single document stream.

Parameters:

ctx (Context) – The Context with which to render.

Returns:

Rendered result.

Raises:

yaml.composer.ComposerError – when there are more than one document in the stream which produce output when rendered, or the document which produces output is not the last document in the stream.

Dumper

class TemplateDumper(stream, default_style=None, default_flow_style=False, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, version=None, tags=None, sort_keys=True)

Bases: SafeDumper

Dumps un-rendered ENYAML templates.

Node Representation

class ForNode(tag, value, start_mark=None, end_mark=None, style=None)

Bases: ScalarNode

Represents a !for expression node.

class SetterNode(tag, value, start_mark=None, end_mark=None, flow_style=None)

Bases: MappingTemplateNode

Represents a !set node.

When rendered, updates the Context with the result. !set nodes are removed from rendered documents.

class ExpressionNode(tag, value, start_mark=None, end_mark=None, style=None)

Bases: ScalarTemplateNode

Represents a !$ node.

When rendered, is replaced by the result of the expression. If the expression evaluates to a template node, it will be rendered.

class FormatStringNode(tag, value, start_mark=None, end_mark=None, style=None)

Bases: ScalarTemplateNode

Represents a !$f node.

When rendered, is replaced by the result of the format-string.

class IfNode(tag, value, start_mark=None, end_mark=None, flow_style=None)

Bases: SequenceTemplateNode

Represents an !if node.

When rendered, is replaced by the first matching node. If no nodes match, but a default is provided, then will be replaced by the default node. If no default is provided, then node will not appear in output.