From 1f824bd620b60dff90233bd4b057c74ada1677a0 Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Mon, 26 Mar 2018 12:06:00 -0500 Subject: [PATCH] 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 --- lib/ansible/playbook/conditional.py | 2 +- lib/ansible/template/__init__.py | 7 +++++-- test/units/template/test_tests_as_filters_warning.py | 7 ++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/ansible/playbook/conditional.py b/lib/ansible/playbook/conditional.py index 33ee54c69e..90c213bde3 100644 --- a/lib/ansible/playbook/conditional.py +++ b/lib/ansible/playbook/conditional.py @@ -176,7 +176,7 @@ class Conditional: ) try: e = templar.environment.overlay() - e.filters.update(templar._get_filters()) + e.filters.update(templar._get_filters(e.filters)) e.tests.update(templar._get_tests()) res = e._parse(conditional, None, None) diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py index 3a2ff89b9c..000c5b91e5 100644 --- a/lib/ansible/template/__init__.py +++ b/lib/ansible/template/__init__.py @@ -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)) - def _get_filters(self): + def _get_filters(self, builtin_filters): ''' 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 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) for fp in self._filter_loader.all(): @@ -678,7 +681,7 @@ class Templar: setattr(myenv, key, ast.literal_eval(val.strip())) # 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()) if escape_backslashes: diff --git a/test/units/template/test_tests_as_filters_warning.py b/test/units/template/test_tests_as_filters_warning.py index 8a33e590c5..5139230317 100644 --- a/test/units/template/test_tests_as_filters_warning.py +++ b/test/units/template/test_tests_as_filters_warning.py @@ -1,5 +1,7 @@ from ansible.template import Templar, display from units.mock.loader import DictDataLoader +from jinja2.filters import FILTERS +from os.path import isabs 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", }) templar = Templar(loader=fake_loader, variables={}) - filters = templar._get_filters() + filters = templar._get_filters(templar.environment.filters) mocker.patch.object(display, 'deprecated') @@ -28,3 +30,6 @@ def test_tests_as_filters_warning(mocker): display.deprecated.reset_mock() filters['bool'](True) assert display.deprecated.call_count == 0 + + # Ensure custom test does not override builtin filter + assert filters.get('abs') != isabs