Commit 9e3291b8 authored by André Anjos's avatar André Anjos

Merge branch 'bob.extension.rc' into 'master'

Automatic injection of bob.extension.rc to jinja variables

Closes #31

See merge request !27
parents 43112b48 271eeb90
Pipeline #29308 passed with stages
in 20 minutes and 15 seconds
......@@ -189,6 +189,16 @@ configuration files and the aggregation would look like the following:
$ jgen variables.yaml template.py 'output-dir/{{ name }}-{{ version }}.py' run.sh 'output-dir/run.sh'
Automatic injection of variables
--------------------------------
Sometimes you want to use variables that are user specific in your jinja templates; For
example, a temp directory that can be different for other users. To allow this, jgen
automatically injects ``bob.extension.rc`` (see :ref:`bob.extension.rc`) into your
variables. Then, you can access ``bob.extension.rc`` using something like:
``rc.variable_name`` to access variables from it in your jinja templates.
.. Place your references here:
.. _yaml: https://en.wikipedia.org/wiki/YAML
.. _jinja2: http://jinja.pocoo.org/docs/
......@@ -3,24 +3,24 @@
'''Utilities for generating configurations for running experiments in batch'''
from bob.extension import rc
import collections
import itertools
import yaml
import jinja2
class _OrderedDict(collections.OrderedDict):
class dict(collections.OrderedDict):
"""An OrderedDict class that can be compared.
This is to avoid sort errors (in Python 3) that happen in jinja internally.
"""
def __lt__(self, other):
return id(self) < id(other)
def _ordered_load(stream, Loader=yaml.Loader,
object_pairs_hook=_OrderedDict):
object_pairs_hook=dict):
'''Loads the contents of the YAML stream into :py:class:`collections.OrderedDict`'s
See: https://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts
......@@ -131,8 +131,8 @@ def expand(data):
# separates "unique" objects from the ones we have to iterate
# pre-assemble return dictionary
iterables = _OrderedDict()
unique = _OrderedDict()
iterables = dict()
unique = dict()
for key, value in data.items():
if isinstance(value, list) and not key.startswith('_'):
iterables[key] = value
......@@ -141,7 +141,7 @@ def expand(data):
# generates all possible combinations of iterables
for values in itertools.product(*iterables.values()):
retval = _OrderedDict(unique)
retval = dict(unique)
keys = list(iterables.keys())
retval.update(dict(zip(keys, values)))
yield retval
......@@ -176,6 +176,7 @@ def generate(variables, template):
env = jinja2.Environment(undefined=jinja2.StrictUndefined)
for c in expand(variables):
c['rc'] = rc
yield env.from_string(template).render(c)
......@@ -206,5 +207,5 @@ def aggregate(variables, template):
'''
env = jinja2.Environment(undefined=jinja2.StrictUndefined)
d = {'cfgset': list(expand(variables))}
d = {'cfgset': list(expand(variables)), 'rc': rc}
return env.from_string(template).render(d)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment