diff --git a/src/yamlprocessor/dataprocess.py b/src/yamlprocessor/dataprocess.py index 15ff443..73e71e2 100755 --- a/src/yamlprocessor/dataprocess.py +++ b/src/yamlprocessor/dataprocess.py @@ -409,17 +409,23 @@ def process_data( item, parent_filenames, variable_map)) if is_merge and type_of_data != type(include_data): raise TypeError() - if is_merge and type_of_data is list: - # For a list, the iterator seems to handle the new items - # perfectly fine. We insert the included list at and after - # the current position. The current item is logically - # replaced by the first item of the inserted list. + if ( + is_merge + and type_of_data is list + and len(include_data) == 1 + ): + # For a list, if the incoming is a single element list, + # then it can replace the original with no issue. + item = data[key] = include_data[0] + elif is_merge and type_of_data is list: + # For a list, if the incoming is not a single element list, + # the iterator will stop working, so we need to re-process + # the list for correctness. del data[key] - item = None for i, include_item in enumerate(include_data): data.insert(key + i, include_item) - if i == 0: - item = include_item + stack.append([data, parent_filenames, variable_map]) + break elif is_merge and type_of_data is dict: # For a dict, the iterator cannot handle size changes, so # we can only iterate over a copy of the original dict. We diff --git a/src/yamlprocessor/tests/test_dataprocess.py b/src/yamlprocessor/tests/test_dataprocess.py index be54142..d343f6c 100644 --- a/src/yamlprocessor/tests/test_dataprocess.py +++ b/src/yamlprocessor/tests/test_dataprocess.py @@ -460,6 +460,31 @@ def test_main_12(tmp_path, yaml): ] +def test_main_12_1(tmp_path, yaml): + """Test main, merge include file with empty list and variable process. + + Issue 35. + """ + root_data = [ + {'name': '${MATTER}'}, + {'INCLUDE': 'void.yaml', 'MERGE': True}, + {'name': '${MATTER}'}, + ] + void_data = [] + infilename = tmp_path / 'root.yaml' + with infilename.open('w') as infile: + yaml.dump(root_data, infile) + include_infilename = tmp_path / 'void.yaml' + with include_infilename.open('w') as infile: + yaml.dump(void_data, infile) + outfilename = tmp_path / 'b.yaml' + main(['--define=MATTER=stuff', str(infilename), str(outfilename)]) + assert yaml.load(outfilename.open()) == [ + {'name': 'stuff'}, + {'name': 'stuff'}, + ] + + def test_main_13(tmp_path, yaml): """Test main, merge include files into a map/object.""" root_data = {