diff --git a/lib/ansible/playbook/conditional.py b/lib/ansible/playbook/conditional.py index 33ee54c69e87c5..90c213bde3db56 100644 --- a/lib/ansible/playbook/conditional.py +++ b/lib/ansible/playbook/conditional.py @@ -176,7 +176,7 @@ def generic_visit(self, node, inside_call=False, inside_yield=False): ) 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 3a2ff89b9c87df..000c5b91e55e85 100644 --- a/lib/ansible/template/__init__.py +++ b/lib/ansible/template/__init__.py @@ -292,7 +292,7 @@ def __init__(self, loader, shared_loader_obj=None, variables=None): )) 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 @@ def _get_filters(self): # 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 @@ def do_template(self, data, preserve_trailing_newlines=True, escape_backslashes= 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 8a33e590c5be40..51392303176fe1 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