Make to_paths handles empty list and mapping (#58)

Make to_paths handles empty list and mapping

Reviewed-by: https://github.com/apps/ansible-zuul
pull/79/head
stoned 2021-06-17 09:26:13 +02:00 committed by GitHub
parent 1b76548d9d
commit 0a2e083c9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 14 deletions

View File

@ -0,0 +1,4 @@
---
bugfixes:
- Also include empty lists and mappings into the output dictionary
(https://github.com/ansible-collections/ansible.utils/pull/58).

View File

@ -22,26 +22,39 @@ def to_paths(var, prepend, wantlist):
if prepend:
var = {prepend: var}
out = {}
def flatten(data, name=""):
def flatten(data, name="", out=None):
if out is None:
out = {}
if isinstance(data, (dict, Mapping, MutableMapping)):
for key, val in data.items():
if name:
if re.match("^[a-zA-Z_][a-zA-Z0-9_]*$", key):
nname = name + ".{key}".format(key=key)
if data:
for key, val in data.items():
if name:
if re.match("^[a-zA-Z_][a-zA-Z0-9_]*$", key):
nname = name + ".{key}".format(key=key)
else:
nname = name + "['{key}']".format(key=key)
else:
nname = name + "['{key}']".format(key=key)
else:
nname = key
flatten(val, nname)
nname = key
flatten(val, nname, out)
elif name:
out[name] = {}
else:
out = {}
elif isinstance(data, list):
for idx, val in enumerate(data):
flatten(val, "{name}[{idx}]".format(name=name, idx=idx))
if data:
for idx, val in enumerate(data):
flatten(
val, "{name}[{idx}]".format(name=name, idx=idx), out
)
elif name:
out[name] = []
else:
out = []
else:
out[name] = data
return out
flatten(var)
out = flatten(var)
if wantlist:
return [out]
return out

View File

@ -0,0 +1,40 @@
---
- ansible.builtin.set_fact:
a:
b: []
c: {}
d:
e: [{}, {}]
f:
g: [[], []]
empty_list: []
empty_mapping: {}
- name: Test filter and lookup plugin with empty list and mapping
assert:
that: "{{ item.result == item.expected }}"
loop:
- result: "{{ a|ansible.utils.to_paths }}"
expected:
b: []
c: {}
d.e[0]: {}
d.e[1]: {}
f.g[0]: []
f.g[1]: []
- result: "{{ lookup('ansible.utils.to_paths', a) }}"
expected:
b: []
c: {}
d.e[0]: {}
d.e[1]: {}
f.g[0]: []
f.g[1]: []
- result: "{{ empty_list|ansible.utils.to_paths }}"
expected: []
- result: "{{ lookup('ansible.utils.to_paths', empty_list) }}"
expected: []
- result: "{{ empty_mapping|ansible.utils.to_paths }}"
expected: {}
- result: "{{ lookup('ansible.utils.to_paths', empty_mapping) }}"
expected: {}

View File

@ -65,3 +65,39 @@ class TestToPaths(unittest.TestCase):
var, to_test, environment=self._environment, wantlist=False
)
self.assertEqual(gotten, paths[to_test])
def test_to_paths_empty_list(self):
var = {"a": []}
expected = {"a": []}
result = to_paths(var, prepend=None, wantlist=None)
self.assertEqual(result, expected)
def test_to_paths_list_of_empty_list(self):
var = {"a": [[], []]}
expected = {"a[0]": [], "a[1]": []}
result = to_paths(var, prepend=None, wantlist=None)
self.assertEqual(result, expected)
def test_to_paths_empty_mapping(self):
var = {"a": {}}
expected = {"a": {}}
result = to_paths(var, prepend=None, wantlist=None)
self.assertEqual(result, expected)
def test_to_paths_list_of_empty_mapping(self):
var = [{}, {}]
expected = {"[0]": {}, "[1]": {}}
result = to_paths(var, prepend=None, wantlist=None)
self.assertEqual(result, expected)
def test_to_paths_only_empty_list(self):
var = []
expected = []
result = to_paths(var, prepend=None, wantlist=None)
self.assertEqual(result, expected)
def test_to_paths_only_empty_mapping(self):
var = {}
expected = {}
result = to_paths(var, prepend=None, wantlist=None)
self.assertEqual(result, expected)