Fix extended package support (#14980)

* Fix package recurive merge bug

* Fixed extended package support
This commit is contained in:
cdce8p 2018-06-16 12:55:32 +02:00 committed by Paulus Schoutsen
parent 2839f0ff5f
commit 7d9bce2153
2 changed files with 41 additions and 39 deletions

View file

@ -548,15 +548,15 @@ def _identify_config_schema(module):
return '', schema
def _recursive_merge(pack_name, comp_name, config, conf, package):
def _recursive_merge(conf, package):
"""Merge package into conf, recursively."""
error = False
for key, pack_conf in package.items():
if isinstance(pack_conf, dict):
if not pack_conf:
continue
conf[key] = conf.get(key, OrderedDict())
_recursive_merge(pack_name, comp_name, config,
conf=conf[key], package=pack_conf)
error = _recursive_merge(conf=conf[key], package=pack_conf)
elif isinstance(pack_conf, list):
if not pack_conf:
@ -566,11 +566,10 @@ def _recursive_merge(pack_name, comp_name, config, conf, package):
else:
if conf.get(key) is not None:
_log_pkg_error(
pack_name, comp_name, config,
'has keys that are defined multiple times')
return key
else:
conf[key] = pack_conf
return error
def merge_packages_config(hass, config, packages,
@ -605,39 +604,34 @@ def merge_packages_config(hass, config, packages,
config[comp_name].extend(cv.ensure_list(comp_conf))
continue
if merge_type == 'dict':
if comp_conf is None:
comp_conf = OrderedDict()
if comp_conf is None:
comp_conf = OrderedDict()
if not isinstance(comp_conf, dict):
_log_pkg_error(
pack_name, comp_name, config,
"cannot be merged. Expected a dict.")
continue
if comp_name not in config:
config[comp_name] = OrderedDict()
if not isinstance(config[comp_name], dict):
_log_pkg_error(
pack_name, comp_name, config,
"cannot be merged. Dict expected in main config.")
continue
for key, val in comp_conf.items():
if key in config[comp_name]:
_log_pkg_error(pack_name, comp_name, config,
"duplicate key '{}'".format(key))
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)
if not isinstance(comp_conf, dict):
_log_pkg_error(
pack_name, comp_name, config,
"cannot be merged. Expected a dict.")
continue
config[comp_name] = comp_conf
if comp_name not in config or config[comp_name] is None:
config[comp_name] = OrderedDict()
if not isinstance(config[comp_name], dict):
_log_pkg_error(
pack_name, comp_name, config,
"cannot be merged. Dict expected in main config.")
continue
if not isinstance(comp_conf, dict):
_log_pkg_error(
pack_name, comp_name, config,
"cannot be merged. Dict expected in package.")
continue
error = _recursive_merge(conf=config[comp_name],
package=comp_conf)
if error:
_log_pkg_error(pack_name, comp_name, config,
"has duplicate key '{}'".format(error))
return config

View file

@ -589,7 +589,7 @@ def test_merge(merge_log_err, hass):
assert len(config['input_boolean']) == 2
assert len(config['input_select']) == 1
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):
@ -656,6 +656,14 @@ def test_merge_type_mismatch(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."""
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': {
'key_3': 3,
}}}
@ -755,7 +763,7 @@ def test_merge_duplicate_keys(merge_log_err, hass):
}
config = {
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)