diff --git a/homeassistant/config.py b/homeassistant/config.py index 4d3d4dd841f..ccf1317e660 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -631,10 +631,9 @@ def _recursive_merge(conf: Dict[str, Any], package: Dict[str, Any]) -> Union[boo error = _recursive_merge(conf=conf[key], package=pack_conf) elif isinstance(pack_conf, list): - if not pack_conf: - continue - conf[key] = cv.ensure_list(conf.get(key)) - conf[key].extend(cv.ensure_list(pack_conf)) + conf[key] = cv.remove_falsy( + cv.ensure_list(conf.get(key)) + cv.ensure_list(pack_conf) + ) else: if conf.get(key) is not None: @@ -669,22 +668,17 @@ async def merge_packages_config( _log_pkg_error(pack_name, comp_name, config, str(ex)) continue - if hasattr(component, "PLATFORM_SCHEMA"): - if not comp_conf: - continue # Ensure we dont add Falsy items to list - config[comp_name] = cv.ensure_list(config.get(comp_name)) - config[comp_name].extend(cv.ensure_list(comp_conf)) - continue + merge_list = hasattr(component, "PLATFORM_SCHEMA") - if hasattr(component, "CONFIG_SCHEMA"): + if not merge_list and hasattr(component, "CONFIG_SCHEMA"): merge_type, _ = _identify_config_schema(component) + merge_list = merge_type == "list" - if merge_type == "list": - if not comp_conf: - continue # Ensure we dont add Falsy items to list - config[comp_name] = cv.ensure_list(config.get(comp_name)) - config[comp_name].extend(cv.ensure_list(comp_conf)) - continue + if merge_list: + config[comp_name] = cv.remove_falsy( + cv.ensure_list(config.get(comp_name)) + cv.ensure_list(comp_conf) + ) + continue if comp_conf is None: comp_conf = OrderedDict() diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index b52a17b2e39..db96f4a2d02 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -11,7 +11,7 @@ from datetime import ( ) from socket import _GLOBAL_DEFAULT_TIMEOUT from numbers import Number -from typing import Any, Union, TypeVar, Callable, Sequence, Dict, Optional +from typing import Any, Union, TypeVar, Callable, List, Dict, Optional from urllib.parse import urlparse from uuid import UUID @@ -191,7 +191,7 @@ def isdir(value: Any) -> str: return dir_in -def ensure_list(value: Union[T, Sequence[T], None]) -> Sequence[T]: +def ensure_list(value: Union[T, List[T], None]) -> List[T]: """Wrap value in list if it is not one.""" if value is None: return [] @@ -207,7 +207,7 @@ def entity_id(value: Any) -> str: raise vol.Invalid("Entity ID {} is an invalid entity id".format(value)) -def entity_ids(value: Union[str, Sequence]) -> Sequence[str]: +def entity_ids(value: Union[str, List]) -> List[str]: """Validate Entity IDs.""" if value is None: raise vol.Invalid("Entity IDs can not be None") @@ -234,7 +234,7 @@ def entity_domain(domain: str): def entities_domain(domain: str): """Validate that entities belong to domain.""" - def validate(values: Union[str, Sequence]) -> Sequence[str]: + def validate(values: Union[str, List]) -> List[str]: """Test if entity domain is domain.""" values = entity_ids(values) for ent_id in values: @@ -370,7 +370,7 @@ def positive_timedelta(value: timedelta) -> timedelta: return value -def remove_falsy(value: Sequence[T]) -> Sequence[T]: +def remove_falsy(value: List[T]) -> List[T]: """Remove falsy values from a list.""" return [v for v in value if v] @@ -562,7 +562,7 @@ def uuid4_hex(value): return result.hex -def ensure_list_csv(value: Any) -> Sequence: +def ensure_list_csv(value: Any) -> List: """Ensure that input is a list or make one from comma-separated string.""" if isinstance(value, str): return [member.strip() for member in value.split(",")] diff --git a/tests/test_config.py b/tests/test_config.py index 6d85712bc25..a67cd345797 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -735,7 +735,7 @@ async def test_merge_once_only_lists(hass): """Test if we have a merge for a comp that may occur only once. Lists.""" packages = { "pack_2": { - "api": {"list_1": ["item_2", "item_3"], "list_2": ["item_1"], "list_3": []} + "api": {"list_1": ["item_2", "item_3"], "list_2": ["item_4"], "list_3": []} } } config = { @@ -745,7 +745,8 @@ async def test_merge_once_only_lists(hass): await config_util.merge_packages_config(hass, config, packages) assert config["api"] == { "list_1": ["item_1", "item_2", "item_3"], - "list_2": ["item_1"], + "list_2": ["item_4"], + "list_3": [], }