From f892cc798c0d709359ec1a6c274da804b2e02b03 Mon Sep 17 00:00:00 2001 From: Marc Pujol Date: Fri, 30 May 2014 08:54:48 +0200 Subject: [PATCH 1/2] Merge and intersect lists without using sets. Using sets for these operations is dangerous because sets cannot contain certain object types (such as lists) and their iteration order is undefined. Fixes #7596 --- lib/ansible/utils/__init__.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 1800a35534..042f0fac5e 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -1003,21 +1003,19 @@ def is_list_of_strings(items): return False return True -def _listify(a): - if not isinstance(a, (list, tuple)): - return [a,] - else: - return a - def list_union(a, b): - set_a = set(_listify(a)) - set_b = set(_listify(b)) - return list(set_a.union(set_b)) + result = list(a) + for i in b: + if i not in result: + result.append(i) + return result def list_intersection(a, b): - set_a = set(_listify(a)) - set_b = set(_listify(b)) - return list(set_a.intersection(set_b)) + result = [] + for i in a: + if i in b: + result.append(i) + return result def safe_eval(expr, locals={}, include_exceptions=False): ''' From d0f82e94e878c0dc4194c8427c70c3d75427da52 Mon Sep 17 00:00:00 2001 From: Marc Pujol Date: Fri, 30 May 2014 15:47:18 +0200 Subject: [PATCH 2/2] Ensure there are no duplicates in the merged/intersected lists --- lib/ansible/utils/__init__.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 042f0fac5e..c9d26e2564 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -1004,17 +1004,20 @@ def is_list_of_strings(items): return True def list_union(a, b): - result = list(a) - for i in b: - if i not in result: - result.append(i) + result = [] + for x in a: + if x not in result: + result.append(x) + for x in b: + if x not in result: + result.append(x) return result def list_intersection(a, b): result = [] - for i in a: - if i in b: - result.append(i) + for x in a: + if x in b and x not in result: + result.append(x) return result def safe_eval(expr, locals={}, include_exceptions=False):