from copy import deepcopy def apply_layer(base: dict, layer: dict): """ Recursively applies key-value pairs from `layer` onto `base`. For each key in `layer`: - If both `base[key]` and `layer[key]` are dictionaries, recursively merge them. - Otherwise, `base[key]` is overwritten (or newly inserted) with `layer[key]`. Note: This function mutates the `base` dictionary in-place. :param base: The target dictionary to be updated. Will be modified directly. :param layer: The source dictionary whose values will be applied to `base`. """ for key, value in layer.items(): # if base and layer value are dicts, apply recursively if type(value) is dict and key in base and type(base[key]) is dict: apply_layer(base[key], value) # else replace the base value with the layer value # or insert the base value else: base[key] = value def merge(pillar_data, deep_copy=True) -> dict: """ Merges multiple pillar data dictionaries into one. The merging is done left-to-right: keys from later dictionaries override those in earlier ones. Nested dictionaries are merged recursively using `apply_layer`. :param pillar_data: Two or more dictionaries to merge. Must contain at least one item. :param deep_copy: If True (default), the first dictionary is deep-copied before merging, preserving the original input data. If False, the first dictionary is modified in-place. :return: A new merged dictionary (if `deep_copy=True`) or the mutated first dictionary (if `deep_copy=False`). Example: merge({'a': 1}, {'b': 2}) → {'a': 1, 'b': 2} merge({'a': {'x': 1}}, {'a': {'y': 2}}) → {'a': {'x': 1, 'y': 2}} """ assert len(pillar_data) > 0, "At least one pillar data is required" merged_pillar = deepcopy(pillar_data[0]) if deep_copy else pillar_data[0] for pillar in pillar_data[1:]: apply_layer(merged_pillar, pillar) return merged_pillar