Source code for roboglia.utils.extyaml

import yaml
import os
import collections


[docs]def load_yaml_with_include(file_name): """Loads a YAML file safely and returns a dictionary with the configuration data. Suppports ``include`` directive. If there is an ``include`` key at the top level in the source file, the files specified will be opened *in the given order* and data will be merged. Updates from a new file can create new keys in the merged dictionary or update the existing ones. At the end the content of the original file is merged in the same manner in the final dictionary. The ``include`` statements are removed from the final dictionary. """ base_path = os.path.dirname(file_name) with open(file_name, 'r') as f: main_dict = yaml.safe_load(f) if 'include' not in main_dict: return main_dict else: full_dict = {} includes = main_dict['include'] del main_dict['include'] for include_file in includes: include_path = os.path.join(base_path, include_file) norm_include_path = os.path.normpath(include_path) with open(norm_include_path, 'r') as f: include_dict = yaml.safe_load(f) deep_update(source=full_dict, overrides=include_dict) return deep_update(source=full_dict, overrides=main_dict)
def deep_update(source, overrides): """ Update a nested dictionary or similar mapping. Modify ``source`` in place. """ for k, v in list(overrides.items()): if isinstance(v, collections.Mapping) and v: returned = deep_update(source.get(k, {}), v) source[k] = returned else: source[k] = overrides[k] return source