diff --git a/heat/engine/hot/functions.py b/heat/engine/hot/functions.py index dd248f4c4b..7ca8943ded 100644 --- a/heat/engine/hot/functions.py +++ b/heat/engine/hot/functions.py @@ -947,11 +947,15 @@ class Repeat(function.Function): keys, lists = six.moves.zip(*for_each.items()) # use empty list for references(None) else validation will fail - values = [[] if value is None else value for value in lists] value_lens = [] - for arg in values: - self._valid_arg(arg) - value_lens.append(len(arg)) + values = [] + for value in lists: + if value is None: + values.append([]) + else: + self._valid_arg(value) + values.append(value) + value_lens.append(len(value)) if not self._nested_loop: if len(set(value_lens)) != 1: raise ValueError(_('For %s, the length of for_each values ' diff --git a/heat/tests/test_hot.py b/heat/tests/test_hot.py index da5965fa4e..900d36ed36 100644 --- a/heat/tests/test_hot.py +++ b/heat/tests/test_hot.py @@ -1105,6 +1105,16 @@ class HOTemplateTest(common.HeatTestCase): self.assertEqual({}, resolved) + def test_merge_containing_repeat_multi_list_no_nested_loop_with_none(self): + snippet = {'map_merge': {'repeat': { + 'template': {'ROLE': 'ROLE', 'NAME': 'NAME'}, + 'for_each': {'ROLE': None, 'NAME': ['n1', 'n2']}, + 'permutations': None}}} + tmpl = template.Template(hot_mitaka_tpl_empty) + resolved = self.resolve(snippet, tmpl) + + self.assertEqual({}, resolved) + def test_map_replace(self): snippet = {'map_replace': [{'f1': 'b1', 'f2': 'b2'}, {'keys': {'f1': 'F1'},