From b76c4c840e339813d0eb811227cb0348e069b291 Mon Sep 17 00:00:00 2001 From: Pilou Date: Mon, 1 Oct 2018 22:30:24 +0200 Subject: [PATCH] WIP: Check that union Jinja filter can be chained (#46298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Check that union Jinja filter can be chained * set filters: fix unexpected templating type error this error occurs with Jinja 2.10 since 32ec69d827393f6b1685bc3b089ea6c341b943e1, for example when union filters are chained: $ ansible all -i localhost, -mdebug -a"msg={{ []|union([])|union([]) }}" localhost | FAILED! => { "msg": "Unexpected templating type error occurred on ({{ []|union([])|union([]) }}): unsupported operand type(s) for +: 'set' and 'list'" } --- lib/ansible/plugins/filter/mathstuff.py | 7 ++++++- test/integration/targets/filters/tasks/main.yml | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/ansible/plugins/filter/mathstuff.py b/lib/ansible/plugins/filter/mathstuff.py index c6ce1df30ae..18093ce6ed6 100644 --- a/lib/ansible/plugins/filter/mathstuff.py +++ b/lib/ansible/plugins/filter/mathstuff.py @@ -54,7 +54,12 @@ def unique(environment, a, case_sensitive=False, attribute=None): error = None try: if HAS_UNIQUE: - c = set(do_unique(environment, a, case_sensitive=case_sensitive, attribute=attribute)) + c = do_unique(environment, a, case_sensitive=case_sensitive, attribute=attribute) + if isinstance(a, collections.Hashable): + c = set(c) + else: + c = list(c) + except Exception as e: if case_sensitive or attribute: raise AnsibleFilterError("Jinja2's unique filter failed and we cannot fall back to Ansible's version " diff --git a/test/integration/targets/filters/tasks/main.yml b/test/integration/targets/filters/tasks/main.yml index 69162c51324..80f84ae15de 100644 --- a/test/integration/targets/filters/tasks/main.yml +++ b/test/integration/targets/filters/tasks/main.yml @@ -237,3 +237,19 @@ that: - "'00:00:00' | random_mac is match('^00:00:00:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]$')" - "'00:00:00' | random_mac != '00:00:00' | random_mac" + +- name: Verify that union can be chained + vars: + unions: '{{ [1,2,3]|union([4,5])|union([6,7]) }}' + assert: + that: + - "unions|type_debug == 'list'" + - "unions|length == 7" + +- name: Test union with unhashable item + vars: + unions: '{{ [1,2,3]|union([{}]) }}' + assert: + that: + - "unions|type_debug == 'list'" + - "unions|length == 4"