mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Perform merges when substituting dict keys (#3062)
This commit is contained in:
		| @@ -1,6 +1,7 @@ | |||||||
| import re | import re | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| from esphome.core import EsphomeError | from esphome.core import EsphomeError | ||||||
|  | from esphome.config_helpers import merge_config | ||||||
|  |  | ||||||
| from esphome import git, yaml_util | from esphome import git, yaml_util | ||||||
| from esphome.const import ( | from esphome.const import ( | ||||||
| @@ -18,26 +19,6 @@ import esphome.config_validation as cv | |||||||
| DOMAIN = CONF_PACKAGES | 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): | def validate_git_package(config: dict): | ||||||
|     new_config = config |     new_config = config | ||||||
|     for key, conf in config.items(): |     for key, conf in config.items(): | ||||||
| @@ -167,7 +148,7 @@ def do_packages_pass(config: dict): | |||||||
|                     package_config = _process_base_package(package_config) |                     package_config = _process_base_package(package_config) | ||||||
|                 if isinstance(package_config, dict): |                 if isinstance(package_config, dict): | ||||||
|                     recursive_package = do_packages_pass(package_config) |                     recursive_package = do_packages_pass(package_config) | ||||||
|                 config = _merge_package(recursive_package, config) |                 config = merge_config(recursive_package, config) | ||||||
|  |  | ||||||
|         del config[CONF_PACKAGES] |         del config[CONF_PACKAGES] | ||||||
|     return config |     return config | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import esphome.config_validation as cv | |||||||
| from esphome import core | from esphome import core | ||||||
| from esphome.const import CONF_SUBSTITUTIONS | from esphome.const import CONF_SUBSTITUTIONS | ||||||
| from esphome.yaml_util import ESPHomeDataBase, make_data_base | from esphome.yaml_util import ESPHomeDataBase, make_data_base | ||||||
|  | from esphome.config_helpers import merge_config | ||||||
|  |  | ||||||
| CODEOWNERS = ["@esphome/core"] | CODEOWNERS = ["@esphome/core"] | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
| @@ -108,7 +109,7 @@ def _substitute_item(substitutions, item, path): | |||||||
|             if sub is not None: |             if sub is not None: | ||||||
|                 item[k] = sub |                 item[k] = sub | ||||||
|         for old, new in replace_keys: |         for old, new in replace_keys: | ||||||
|             item[new] = item[old] |             item[new] = merge_config(item.get(old), item.get(new)) | ||||||
|             del item[old] |             del item[old] | ||||||
|     elif isinstance(item, str): |     elif isinstance(item, str): | ||||||
|         sub = _expand_substitutions(substitutions, item, path) |         sub = _expand_substitutions(substitutions, item, path) | ||||||
|   | |||||||
| @@ -23,3 +23,23 @@ def read_config_file(path): | |||||||
|         return data["content"] |         return data["content"] | ||||||
|  |  | ||||||
|     return read_file(path) |     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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user