Don't overwrite builtin jinja2 filters with tests (#37881)

* Don't overwrite builtin jinja2 filters with tests. Fixes #37856

* Fix tests and other callers of _get_filters
This commit is contained in:
Matt Martz 2018-03-26 12:06:00 -05:00 committed by Adam Miller
parent 169209c32a
commit 1f824bd620
3 changed files with 12 additions and 4 deletions

View file

@ -176,7 +176,7 @@ class Conditional:
) )
try: try:
e = templar.environment.overlay() e = templar.environment.overlay()
e.filters.update(templar._get_filters()) e.filters.update(templar._get_filters(e.filters))
e.tests.update(templar._get_tests()) e.tests.update(templar._get_tests())
res = e._parse(conditional, None, None) res = e._parse(conditional, None, None)

View file

@ -292,7 +292,7 @@ class Templar:
)) ))
self._no_type_regex = re.compile(r'.*\|\s*(?:%s)\s*(?:%s)?$' % ('|'.join(C.STRING_TYPE_FILTERS), self.environment.variable_end_string)) self._no_type_regex = re.compile(r'.*\|\s*(?:%s)\s*(?:%s)?$' % ('|'.join(C.STRING_TYPE_FILTERS), self.environment.variable_end_string))
def _get_filters(self): def _get_filters(self, builtin_filters):
''' '''
Returns filter plugins, after loading and caching them if need be Returns filter plugins, after loading and caching them if need be
''' '''
@ -304,6 +304,9 @@ class Templar:
# TODO: Remove registering tests as filters in 2.9 # TODO: Remove registering tests as filters in 2.9
for name, func in self._get_tests().items(): for name, func in self._get_tests().items():
if name in builtin_filters:
# If we have a custom test named the same as a builtin filter, don't register as a filter
continue
self._filters[name] = tests_as_filters_warning(name, func) self._filters[name] = tests_as_filters_warning(name, func)
for fp in self._filter_loader.all(): for fp in self._filter_loader.all():
@ -678,7 +681,7 @@ class Templar:
setattr(myenv, key, ast.literal_eval(val.strip())) setattr(myenv, key, ast.literal_eval(val.strip()))
# Adds Ansible custom filters and tests # Adds Ansible custom filters and tests
myenv.filters.update(self._get_filters()) myenv.filters.update(self._get_filters(myenv.filters))
myenv.tests.update(self._get_tests()) myenv.tests.update(self._get_tests())
if escape_backslashes: if escape_backslashes:

View file

@ -1,5 +1,7 @@
from ansible.template import Templar, display from ansible.template import Templar, display
from units.mock.loader import DictDataLoader from units.mock.loader import DictDataLoader
from jinja2.filters import FILTERS
from os.path import isabs
def test_tests_as_filters_warning(mocker): def test_tests_as_filters_warning(mocker):
@ -7,7 +9,7 @@ def test_tests_as_filters_warning(mocker):
"/path/to/my_file.txt": "foo\n", "/path/to/my_file.txt": "foo\n",
}) })
templar = Templar(loader=fake_loader, variables={}) templar = Templar(loader=fake_loader, variables={})
filters = templar._get_filters() filters = templar._get_filters(templar.environment.filters)
mocker.patch.object(display, 'deprecated') mocker.patch.object(display, 'deprecated')
@ -28,3 +30,6 @@ def test_tests_as_filters_warning(mocker):
display.deprecated.reset_mock() display.deprecated.reset_mock()
filters['bool'](True) filters['bool'](True)
assert display.deprecated.call_count == 0 assert display.deprecated.call_count == 0
# Ensure custom test does not override builtin filter
assert filters.get('abs') != isabs