mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Fix extended package support (#14980)
* Fix package recurive merge bug * Fixed extended package support
This commit is contained in:
parent
2839f0ff5f
commit
7d9bce2153
@ -548,15 +548,15 @@ def _identify_config_schema(module):
|
|||||||
return '', schema
|
return '', schema
|
||||||
|
|
||||||
|
|
||||||
def _recursive_merge(pack_name, comp_name, config, conf, package):
|
def _recursive_merge(conf, package):
|
||||||
"""Merge package into conf, recursively."""
|
"""Merge package into conf, recursively."""
|
||||||
|
error = False
|
||||||
for key, pack_conf in package.items():
|
for key, pack_conf in package.items():
|
||||||
if isinstance(pack_conf, dict):
|
if isinstance(pack_conf, dict):
|
||||||
if not pack_conf:
|
if not pack_conf:
|
||||||
continue
|
continue
|
||||||
conf[key] = conf.get(key, OrderedDict())
|
conf[key] = conf.get(key, OrderedDict())
|
||||||
_recursive_merge(pack_name, comp_name, config,
|
error = _recursive_merge(conf=conf[key], package=pack_conf)
|
||||||
conf=conf[key], package=pack_conf)
|
|
||||||
|
|
||||||
elif isinstance(pack_conf, list):
|
elif isinstance(pack_conf, list):
|
||||||
if not pack_conf:
|
if not pack_conf:
|
||||||
@ -566,11 +566,10 @@ def _recursive_merge(pack_name, comp_name, config, conf, package):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
if conf.get(key) is not None:
|
if conf.get(key) is not None:
|
||||||
_log_pkg_error(
|
return key
|
||||||
pack_name, comp_name, config,
|
|
||||||
'has keys that are defined multiple times')
|
|
||||||
else:
|
else:
|
||||||
conf[key] = pack_conf
|
conf[key] = pack_conf
|
||||||
|
return error
|
||||||
|
|
||||||
|
|
||||||
def merge_packages_config(hass, config, packages,
|
def merge_packages_config(hass, config, packages,
|
||||||
@ -605,7 +604,6 @@ def merge_packages_config(hass, config, packages,
|
|||||||
config[comp_name].extend(cv.ensure_list(comp_conf))
|
config[comp_name].extend(cv.ensure_list(comp_conf))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if merge_type == 'dict':
|
|
||||||
if comp_conf is None:
|
if comp_conf is None:
|
||||||
comp_conf = OrderedDict()
|
comp_conf = OrderedDict()
|
||||||
|
|
||||||
@ -615,7 +613,7 @@ def merge_packages_config(hass, config, packages,
|
|||||||
"cannot be merged. Expected a dict.")
|
"cannot be merged. Expected a dict.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if comp_name not in config:
|
if comp_name not in config or config[comp_name] is None:
|
||||||
config[comp_name] = OrderedDict()
|
config[comp_name] = OrderedDict()
|
||||||
|
|
||||||
if not isinstance(config[comp_name], dict):
|
if not isinstance(config[comp_name], dict):
|
||||||
@ -623,21 +621,17 @@ def merge_packages_config(hass, config, packages,
|
|||||||
pack_name, comp_name, config,
|
pack_name, comp_name, config,
|
||||||
"cannot be merged. Dict expected in main config.")
|
"cannot be merged. Dict expected in main config.")
|
||||||
continue
|
continue
|
||||||
|
if not isinstance(comp_conf, dict):
|
||||||
|
_log_pkg_error(
|
||||||
|
pack_name, comp_name, config,
|
||||||
|
"cannot be merged. Dict expected in package.")
|
||||||
|
continue
|
||||||
|
|
||||||
for key, val in comp_conf.items():
|
error = _recursive_merge(conf=config[comp_name],
|
||||||
if key in config[comp_name]:
|
package=comp_conf)
|
||||||
|
if error:
|
||||||
_log_pkg_error(pack_name, comp_name, config,
|
_log_pkg_error(pack_name, comp_name, config,
|
||||||
"duplicate key '{}'".format(key))
|
"has duplicate key '{}'".format(error))
|
||||||
continue
|
|
||||||
config[comp_name][key] = val
|
|
||||||
continue
|
|
||||||
|
|
||||||
# The last merge type are sections that require recursive merging
|
|
||||||
if comp_name in config:
|
|
||||||
_recursive_merge(pack_name, comp_name, config,
|
|
||||||
conf=config[comp_name], package=comp_conf)
|
|
||||||
continue
|
|
||||||
config[comp_name] = comp_conf
|
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ def test_merge(merge_log_err, hass):
|
|||||||
assert len(config['input_boolean']) == 2
|
assert len(config['input_boolean']) == 2
|
||||||
assert len(config['input_select']) == 1
|
assert len(config['input_select']) == 1
|
||||||
assert len(config['light']) == 3
|
assert len(config['light']) == 3
|
||||||
assert config['wake_on_lan'] is None
|
assert isinstance(config['wake_on_lan'], OrderedDict)
|
||||||
|
|
||||||
|
|
||||||
def test_merge_try_falsy(merge_log_err, hass):
|
def test_merge_try_falsy(merge_log_err, hass):
|
||||||
@ -656,6 +656,14 @@ def test_merge_type_mismatch(merge_log_err, hass):
|
|||||||
|
|
||||||
def test_merge_once_only_keys(merge_log_err, hass):
|
def test_merge_once_only_keys(merge_log_err, hass):
|
||||||
"""Test if we have a merge for a comp that may occur only once. Keys."""
|
"""Test if we have a merge for a comp that may occur only once. Keys."""
|
||||||
|
packages = {'pack_2': {'api': None}}
|
||||||
|
config = {
|
||||||
|
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||||
|
'api': None,
|
||||||
|
}
|
||||||
|
config_util.merge_packages_config(hass, config, packages)
|
||||||
|
assert config['api'] == OrderedDict()
|
||||||
|
|
||||||
packages = {'pack_2': {'api': {
|
packages = {'pack_2': {'api': {
|
||||||
'key_3': 3,
|
'key_3': 3,
|
||||||
}}}
|
}}}
|
||||||
@ -755,7 +763,7 @@ def test_merge_duplicate_keys(merge_log_err, hass):
|
|||||||
}
|
}
|
||||||
config = {
|
config = {
|
||||||
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||||
'input_select': {'ib1': None},
|
'input_select': {'ib1': 1},
|
||||||
}
|
}
|
||||||
config_util.merge_packages_config(hass, config, packages)
|
config_util.merge_packages_config(hass, config, packages)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user