Add back _contains_vars method as maybe_template (#58290)

* Add back _contains_vars method as maybe_template. Fixes #58282

* Remove template guard in a few places

* maybe_template sounds like it might template something, rename to is_possibly_template

* Add tests for is_possibly_template
This commit is contained in:
Matt Martz 2019-06-25 10:54:37 -05:00 committed by GitHub
parent f5b9bd81fc
commit e32d60bbcd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 7 deletions

View file

@ -351,8 +351,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
# template the role name now, if needed
all_vars = variable_manager.get_vars(play=play, task=ir)
templar = Templar(loader=loader, variables=all_vars)
if templar.is_template(ir._role_name):
ir._role_name = templar.template(ir._role_name)
ir._role_name = templar.template(ir._role_name)
# uses compiled list from object
blocks, _ = ir.get_block_list(variable_manager=variable_manager, loader=loader)

View file

@ -129,8 +129,7 @@ class RoleDefinition(Base, Conditional, Taggable, CollectionSearch):
if self._variable_manager:
all_vars = self._variable_manager.get_vars(play=self._play)
templar = Templar(loader=self._loader, variables=all_vars)
if templar.is_template(role_name):
role_name = templar.template(role_name)
role_name = templar.template(role_name)
return role_name

View file

@ -535,7 +535,7 @@ class Templar:
if isinstance(variable, string_types):
result = variable
if self.is_template(variable):
if self.is_possibly_template(variable):
# Check to see if the string we are trying to render is just referencing a single
# var. In this case we don't want to accidentally change the type of the variable
# to a string by using the jinja template renderer. We just want to pass it.
@ -631,7 +631,7 @@ class Templar:
return variable
def is_template(self, data):
''' lets us know if data has a template'''
'''lets us know if data has a template'''
if isinstance(data, string_types):
return is_template(data, self.environment)
elif isinstance(data, (list, tuple)):
@ -644,7 +644,26 @@ class Templar:
return True
return False
templatable = _contains_vars = is_template
templatable = is_template
def is_possibly_template(self, data):
'''Determines if a string looks like a template, by seeing if it
contains a jinja2 start delimiter. Does not guarantee that the string
is actually a template.
This is different than ``is_template`` which is more strict.
This method may return ``True`` on a string that is not templatable.
Useful when guarding passing a string for templating, but when
you want to allow the templating engine to make the final
assessment which may result in ``TemplateSyntaxError``.
'''
env = self.environment
if isinstance(data, string_types):
for marker in (env.block_start_string, env.variable_start_string, env.comment_start_string):
if marker in data:
return True
return False
def _convert_bare_variable(self, variable):
'''

View file

@ -104,6 +104,42 @@ class TestTemplarTemplate(BaseTemplar, unittest.TestCase):
# self.assertEqual(res['{{ a_keyword }}'], "blip")
print(res)
def test_is_possibly_template_true(self):
tests = [
'{{ foo }}',
'{% foo %}',
'{# foo #}',
'{# {{ foo }} #}',
'{# {{ nothing }} {# #}',
'{# {{ nothing }} {# #} #}',
'{% raw %}{{ foo }}{% endraw %}',
'{{',
'{%',
'{#',
'{% raw',
]
for test in tests:
self.assertTrue(self.templar.is_possibly_template(test))
def test_is_possibly_template_false(self):
tests = [
'{',
'%',
'#',
'foo',
'}}',
'%}',
'raw %}',
'#}',
]
for test in tests:
self.assertFalse(self.templar.is_possibly_template(test))
def test_is_possible_template(self):
"""This test ensures that a broken template still gets templated"""
# Purposefully invalid jinja
self.assertRaises(AnsibleError, self.templar.template, '{{ foo|default(False)) }}')
def test_is_template_true(self):
tests = [
'{{ foo }}',