From 28b65cb810fc0f8277cb67b20b4be782ea7138ca Mon Sep 17 00:00:00 2001 From: Joshua Spence Date: Tue, 25 Jan 2022 09:46:42 +1100 Subject: [PATCH] Perform merges when substituting dict keys (#3062) --- esphome/components/packages/__init__.py | 23 ++------------------ esphome/components/substitutions/__init__.py | 3 ++- esphome/config_helpers.py | 20 +++++++++++++++++ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/esphome/components/packages/__init__.py b/esphome/components/packages/__init__.py index 7483d65b9d..67220cae08 100644 --- a/esphome/components/packages/__init__.py +++ b/esphome/components/packages/__init__.py @@ -1,6 +1,7 @@ import re from pathlib import Path from esphome.core import EsphomeError +from esphome.config_helpers import merge_config from esphome import git, yaml_util from esphome.const import ( @@ -18,26 +19,6 @@ import esphome.config_validation as cv DOMAIN = CONF_PACKAGES -def _merge_package(full_old, full_new): - def merge(old, new): - # pylint: disable=no-else-return - if isinstance(new, dict): - if not isinstance(old, dict): - return new - res = old.copy() - for k, v in new.items(): - res[k] = merge(old[k], v) if k in old else v - return res - elif isinstance(new, list): - if not isinstance(old, list): - return new - return old + new - - return new - - return merge(full_old, full_new) - - def validate_git_package(config: dict): new_config = config for key, conf in config.items(): @@ -167,7 +148,7 @@ def do_packages_pass(config: dict): package_config = _process_base_package(package_config) if isinstance(package_config, dict): recursive_package = do_packages_pass(package_config) - config = _merge_package(recursive_package, config) + config = merge_config(recursive_package, config) del config[CONF_PACKAGES] return config diff --git a/esphome/components/substitutions/__init__.py b/esphome/components/substitutions/__init__.py index 0cef417c15..6188b14b35 100644 --- a/esphome/components/substitutions/__init__.py +++ b/esphome/components/substitutions/__init__.py @@ -5,6 +5,7 @@ import esphome.config_validation as cv from esphome import core from esphome.const import CONF_SUBSTITUTIONS from esphome.yaml_util import ESPHomeDataBase, make_data_base +from esphome.config_helpers import merge_config CODEOWNERS = ["@esphome/core"] _LOGGER = logging.getLogger(__name__) @@ -108,7 +109,7 @@ def _substitute_item(substitutions, item, path): if sub is not None: item[k] = sub for old, new in replace_keys: - item[new] = item[old] + item[new] = merge_config(item.get(old), item.get(new)) del item[old] elif isinstance(item, str): sub = _expand_substitutions(substitutions, item, path) diff --git a/esphome/config_helpers.py b/esphome/config_helpers.py index a88c5983b5..72362a3d73 100644 --- a/esphome/config_helpers.py +++ b/esphome/config_helpers.py @@ -23,3 +23,23 @@ def read_config_file(path): return data["content"] return read_file(path) + + +def merge_config(full_old, full_new): + def merge(old, new): + # pylint: disable=no-else-return + if isinstance(new, dict): + if not isinstance(old, dict): + return new + res = old.copy() + for k, v in new.items(): + res[k] = merge(old[k], v) if k in old else v + return res + elif isinstance(new, list): + if not isinstance(old, list): + return new + return old + new + + return new + + return merge(full_old, full_new)