Skip to content

Commit

Permalink
template: fix KeyError: 'undefined variable: 0
Browse files Browse the repository at this point in the history
For compatibility with the Context.get_all() implementation
in jinja 2.9, make AnsibleJ2Vars implement collections.Mapping.
Also, make AnsibleJ2Template.newcontext() handle dict type
for the 'vars' parameter.

See: pallets/jinja@d67f0fd
Fixes: ansible#20494
  • Loading branch information
zmedico committed Aug 9, 2017
1 parent 760015f commit 64fd941
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
9 changes: 8 additions & 1 deletion lib/ansible/template/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,11 @@ class AnsibleJ2Template(jinja2.environment.Template):
'''

def new_context(self, vars=None, shared=False, locals=None):
return self.environment.context_class(self.environment, vars.add_locals(locals), self.name, self.blocks)
if vars is not None:
if isinstance(vars, dict):
vars = vars.copy()
if locals is not None:
vars.update(locals)
else:
vars = vars.add_locals(locals)
return self.environment.context_class(self.environment, vars, self.name, self.blocks)
14 changes: 13 additions & 1 deletion lib/ansible/template/vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from collections import Mapping

from jinja2.utils import missing

from ansible.module_utils.six import iteritems
Expand All @@ -28,7 +30,7 @@
__all__ = ['AnsibleJ2Vars']


class AnsibleJ2Vars:
class AnsibleJ2Vars(Mapping):
'''
Helper class to template all variable content before jinja2 sees it. This is
done by hijacking the variable storage that jinja2 uses, and overriding __contains__
Expand Down Expand Up @@ -69,6 +71,16 @@ def __contains__(self, k):
return True
return False

def __iter__(self):
keys = set()
keys.update(self._templar._available_variables, self._locals, self._globals, *self._extras)
return iter(keys)

def __len__(self):
keys = set()
keys.update(self._templar._available_variables, self._locals, self._globals, *self._extras)
return len(keys)

def __getitem__(self, varname):
if varname not in self._templar._available_variables:
if varname in self._locals:
Expand Down

0 comments on commit 64fd941

Please sign in to comment.