From d8a49b14e5c229bdaa3b0fb61976eb7afe5ecb3d Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Thu, 16 Nov 2023 10:56:47 +0100 Subject: [PATCH] Use relative paths in configuration validation error messages (#104064) --- homeassistant/components/mqtt/__init__.py | 2 +- homeassistant/config.py | 49 ++++-- homeassistant/helpers/check_config.py | 12 +- tests/helpers/test_check_config.py | 5 +- tests/snapshots/test_config.ambr | 178 +++++++++++----------- tests/test_config.py | 8 +- 6 files changed, 141 insertions(+), 113 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 931615bf0ac..83e6dae55b1 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -249,7 +249,7 @@ async def async_check_config_schema( integration = await async_get_integration(hass, DOMAIN) # pylint: disable-next=protected-access message = conf_util.format_schema_error( - ex, domain, config, integration.documentation + hass, ex, domain, config, integration.documentation ) raise ServiceValidationError( message, diff --git a/homeassistant/config.py b/homeassistant/config.py index 2176c111867..a33acead870 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -496,7 +496,7 @@ def async_log_schema_error( """Log a schema validation error.""" if hass is not None: async_notify_setup_error(hass, domain, link) - message = format_schema_error(ex, domain, config, link) + message = format_schema_error(hass, ex, domain, config, link) _LOGGER.error(message) @@ -590,7 +590,13 @@ def find_annotation( return find_annotation_rec(config, list(path), None) +def _relpath(hass: HomeAssistant, path: str) -> str: + """Return path relative to the Home Assistant config dir.""" + return os.path.relpath(path, hass.config.config_dir) + + def stringify_invalid( + hass: HomeAssistant, ex: vol.Invalid, domain: str, config: dict, @@ -613,7 +619,7 @@ def stringify_invalid( else: message_suffix = "" if annotation := find_annotation(config, ex.path): - message_prefix += f" at {annotation[0]}, line {annotation[1]}" + message_prefix += f" at {_relpath(hass, annotation[0])}, line {annotation[1]}" path = "->".join(str(m) for m in ex.path) if ex.error_message == "extra keys not allowed": return ( @@ -643,6 +649,7 @@ def stringify_invalid( def humanize_error( + hass: HomeAssistant, validation_error: vol.Invalid, domain: str, config: dict, @@ -657,12 +664,14 @@ def humanize_error( if isinstance(validation_error, vol.MultipleInvalid): return "\n".join( sorted( - humanize_error(sub_error, domain, config, link, max_sub_error_length) + humanize_error( + hass, sub_error, domain, config, link, max_sub_error_length + ) for sub_error in validation_error.errors ) ) return stringify_invalid( - validation_error, domain, config, link, max_sub_error_length + hass, validation_error, domain, config, link, max_sub_error_length ) @@ -681,10 +690,14 @@ def format_homeassistant_error( @callback def format_schema_error( - ex: vol.Invalid, domain: str, config: dict, link: str | None = None + hass: HomeAssistant, + ex: vol.Invalid, + domain: str, + config: dict, + link: str | None = None, ) -> str: """Format configuration validation error.""" - return humanize_error(ex, domain, config, link) + return humanize_error(hass, ex, domain, config, link) async def async_process_ha_core_config(hass: HomeAssistant, config: dict) -> None: @@ -806,15 +819,19 @@ async def async_process_ha_core_config(hass: HomeAssistant, config: dict) -> Non hac.units = get_unit_system(config[CONF_UNIT_SYSTEM]) -def _log_pkg_error(package: str, component: str, config: dict, message: str) -> None: +def _log_pkg_error( + hass: HomeAssistant, package: str, component: str, config: dict, message: str +) -> None: """Log an error while merging packages.""" message = f"Package {package} setup failed. {message}" pack_config = config[CONF_CORE][CONF_PACKAGES].get(package, config) - message += ( - f" (See {getattr(pack_config, '__config_file__', '?')}:" - f"{getattr(pack_config, '__line__', '?')})." - ) + config_file = getattr(pack_config, "__config_file__", None) + if config_file: + config_file = _relpath(hass, config_file) + else: + config_file = "?" + message += f" (See {config_file}:{getattr(pack_config, '__line__', '?')})." _LOGGER.error(message) @@ -893,7 +910,9 @@ async def merge_packages_config( hass: HomeAssistant, config: dict, packages: dict[str, Any], - _log_pkg_error: Callable[[str, str, dict, str], None] = _log_pkg_error, + _log_pkg_error: Callable[ + [HomeAssistant, str, str, dict, str], None + ] = _log_pkg_error, ) -> dict: """Merge packages into the top-level configuration. Mutate config.""" PACKAGES_CONFIG_SCHEMA(packages) @@ -912,6 +931,7 @@ async def merge_packages_config( component = integration.get_component() except LOAD_EXCEPTIONS as ex: _log_pkg_error( + hass, pack_name, comp_name, config, @@ -919,7 +939,7 @@ async def merge_packages_config( ) continue except INTEGRATION_LOAD_EXCEPTIONS as ex: - _log_pkg_error(pack_name, comp_name, config, str(ex)) + _log_pkg_error(hass, pack_name, comp_name, config, str(ex)) continue try: @@ -953,6 +973,7 @@ async def merge_packages_config( if not isinstance(comp_conf, dict): _log_pkg_error( + hass, pack_name, comp_name, config, @@ -965,6 +986,7 @@ async def merge_packages_config( if not isinstance(config[comp_name], dict): _log_pkg_error( + hass, pack_name, comp_name, config, @@ -975,6 +997,7 @@ async def merge_packages_config( duplicate_key = _recursive_merge(conf=config[comp_name], package=comp_conf) if duplicate_key: _log_pkg_error( + hass, pack_name, comp_name, config, diff --git a/homeassistant/helpers/check_config.py b/homeassistant/helpers/check_config.py index ddc8dce9ec8..7466ddc6179 100644 --- a/homeassistant/helpers/check_config.py +++ b/homeassistant/helpers/check_config.py @@ -93,7 +93,11 @@ async def async_check_ha_config_file( # noqa: C901 async_clear_install_history(hass) def _pack_error( - package: str, component: str, config: ConfigType, message: str + hass: HomeAssistant, + package: str, + component: str, + config: ConfigType, + message: str, ) -> None: """Handle errors from packages.""" message = f"Package {package} setup failed. {message}" @@ -109,7 +113,7 @@ async def async_check_ha_config_file( # noqa: C901 ) -> None: """Handle errors from components.""" if isinstance(ex, vol.Invalid): - message = format_schema_error(ex, domain, component_config) + message = format_schema_error(hass, ex, domain, component_config) else: message = format_homeassistant_error(ex, domain, component_config) if domain in frontend_dependencies: @@ -158,7 +162,9 @@ async def async_check_ha_config_file( # noqa: C901 result[CONF_CORE] = core_config except vol.Invalid as err: result.add_error( - format_schema_error(err, CONF_CORE, core_config), CONF_CORE, core_config + format_schema_error(hass, err, CONF_CORE, core_config), + CONF_CORE, + core_config, ) core_config = {} diff --git a/tests/helpers/test_check_config.py b/tests/helpers/test_check_config.py index 589f71a791d..82500cb0b30 100644 --- a/tests/helpers/test_check_config.py +++ b/tests/helpers/test_check_config.py @@ -82,9 +82,8 @@ async def test_bad_core_config(hass: HomeAssistant) -> None: error = CheckConfigError( ( - "Invalid config for [homeassistant] at " - f"{hass.config.path(YAML_CONFIG_FILE)}, line 2: " - "not a valid value for dictionary value 'unit_system', got 'bad'." + f"Invalid config for [homeassistant] at {YAML_CONFIG_FILE}, line 2:" + " not a valid value for dictionary value 'unit_system', got 'bad'." ), "homeassistant", {"unit_system": "bad"}, diff --git a/tests/snapshots/test_config.ambr b/tests/snapshots/test_config.ambr index bc0dd8830e0..97faac40bf5 100644 --- a/tests/snapshots/test_config.ambr +++ b/tests/snapshots/test_config.ambr @@ -3,47 +3,47 @@ list([ dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 6: required key 'platform' not provided.", + 'message': "Invalid config for [iot_domain] at configuration.yaml, line 6: required key 'platform' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 9: expected str for dictionary value 'option1', got 123.", + 'message': "Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 9: expected str for dictionary value 'option1', got 123.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 12: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", + 'message': "Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 12: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 18: required key 'option1' not provided. - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 19: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 20: expected str for dictionary value 'option2', got 123. + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 18: required key 'option1' not provided. + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 19: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 20: expected str for dictionary value 'option2', got 123. ''', }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_2] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 27: required key 'host' not provided.", + 'message': "Invalid config for [adr_0007_2] at configuration.yaml, line 27: required key 'host' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_3] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 32: expected int for dictionary value 'adr_0007_3->port', got 'foo'.", + 'message': "Invalid config for [adr_0007_3] at configuration.yaml, line 32: expected int for dictionary value 'adr_0007_3->port', got 'foo'.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_4] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 37: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option", + 'message': "Invalid config for [adr_0007_4] at configuration.yaml, line 37: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 43: required key 'host' not provided. - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 44: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 45: expected int for dictionary value 'adr_0007_5->port', got 'foo'. + Invalid config for [adr_0007_5] at configuration.yaml, line 43: required key 'host' not provided. + Invalid config for [adr_0007_5] at configuration.yaml, line 44: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option + Invalid config for [adr_0007_5] at configuration.yaml, line 45: expected int for dictionary value 'adr_0007_5->port', got 'foo'. ''', }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [custom_validator_ok_2] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 52: required key 'host' not provided.", + 'message': "Invalid config for [custom_validator_ok_2] at configuration.yaml, line 52: required key 'host' not provided.", }), dict({ 'has_exc_info': True, @@ -59,47 +59,47 @@ list([ dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain] at /fixtures/core/config/component_validation/basic_include/integrations/iot_domain.yaml, line 5: required key 'platform' not provided.", + 'message': "Invalid config for [iot_domain] at integrations/iot_domain.yaml, line 5: required key 'platform' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic_include/integrations/iot_domain.yaml, line 8: expected str for dictionary value 'option1', got 123.", + 'message': "Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 8: expected str for dictionary value 'option1', got 123.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic_include/integrations/iot_domain.yaml, line 11: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", + 'message': "Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 11: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic_include/integrations/iot_domain.yaml, line 17: required key 'option1' not provided. - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic_include/integrations/iot_domain.yaml, line 18: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic_include/integrations/iot_domain.yaml, line 19: expected str for dictionary value 'option2', got 123. + Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 17: required key 'option1' not provided. + Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 18: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option + Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 19: expected str for dictionary value 'option2', got 123. ''', }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_2] at /fixtures/core/config/component_validation/basic_include/configuration.yaml, line 3: required key 'host' not provided.", + 'message': "Invalid config for [adr_0007_2] at configuration.yaml, line 3: required key 'host' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_3] at /fixtures/core/config/component_validation/basic_include/integrations/adr_0007_3.yaml, line 3: expected int for dictionary value 'adr_0007_3->port', got 'foo'.", + 'message': "Invalid config for [adr_0007_3] at integrations/adr_0007_3.yaml, line 3: expected int for dictionary value 'adr_0007_3->port', got 'foo'.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_4] at /fixtures/core/config/component_validation/basic_include/integrations/adr_0007_4.yaml, line 3: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option", + 'message': "Invalid config for [adr_0007_4] at integrations/adr_0007_4.yaml, line 3: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic_include/configuration.yaml, line 6: required key 'host' not provided. - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic_include/integrations/adr_0007_5.yaml, line 5: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic_include/integrations/adr_0007_5.yaml, line 6: expected int for dictionary value 'adr_0007_5->port', got 'foo'. + Invalid config for [adr_0007_5] at configuration.yaml, line 6: required key 'host' not provided. + Invalid config for [adr_0007_5] at integrations/adr_0007_5.yaml, line 5: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option + Invalid config for [adr_0007_5] at integrations/adr_0007_5.yaml, line 6: expected int for dictionary value 'adr_0007_5->port', got 'foo'. ''', }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [custom_validator_ok_2] at /fixtures/core/config/component_validation/basic_include/configuration.yaml, line 8: required key 'host' not provided.", + 'message': "Invalid config for [custom_validator_ok_2] at configuration.yaml, line 8: required key 'host' not provided.", }), dict({ 'has_exc_info': True, @@ -115,22 +115,22 @@ list([ dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain] at /fixtures/core/config/component_validation/include_dir_list/iot_domain/iot_domain_2.yaml, line 2: required key 'platform' not provided.", + 'message': "Invalid config for [iot_domain] at iot_domain/iot_domain_2.yaml, line 2: required key 'platform' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_list/iot_domain/iot_domain_3.yaml, line 3: expected str for dictionary value 'option1', got 123.", + 'message': "Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_3.yaml, line 3: expected str for dictionary value 'option1', got 123.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_list/iot_domain/iot_domain_4.yaml, line 3: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", + 'message': "Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_4.yaml, line 3: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_list/iot_domain/iot_domain_5.yaml, line 5: required key 'option1' not provided. - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_list/iot_domain/iot_domain_5.yaml, line 6: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_list/iot_domain/iot_domain_5.yaml, line 7: expected str for dictionary value 'option2', got 123. + Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_5.yaml, line 5: required key 'option1' not provided. + Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_5.yaml, line 6: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option + Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_5.yaml, line 7: expected str for dictionary value 'option2', got 123. ''', }), dict({ @@ -147,22 +147,22 @@ list([ dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain] at /fixtures/core/config/component_validation/include_dir_merge_list/iot_domain/iot_domain_1.yaml, line 5: required key 'platform' not provided.", + 'message': "Invalid config for [iot_domain] at iot_domain/iot_domain_1.yaml, line 5: required key 'platform' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_merge_list/iot_domain/iot_domain_2.yaml, line 3: expected str for dictionary value 'option1', got 123.", + 'message': "Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_2.yaml, line 3: expected str for dictionary value 'option1', got 123.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_merge_list/iot_domain/iot_domain_2.yaml, line 6: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", + 'message': "Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_2.yaml, line 6: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_merge_list/iot_domain/iot_domain_2.yaml, line 12: required key 'option1' not provided. - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_merge_list/iot_domain/iot_domain_2.yaml, line 13: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/include_dir_merge_list/iot_domain/iot_domain_2.yaml, line 14: expected str for dictionary value 'option2', got 123. + Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_2.yaml, line 12: required key 'option1' not provided. + Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_2.yaml, line 13: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option + Invalid config for [iot_domain.non_adr_0007] at iot_domain/iot_domain_2.yaml, line 14: expected str for dictionary value 'option2', got 123. ''', }), dict({ @@ -179,47 +179,47 @@ list([ dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 11: required key 'platform' not provided.", + 'message': "Invalid config for [iot_domain] at configuration.yaml, line 11: required key 'platform' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 16: expected str for dictionary value 'option1', got 123.", + 'message': "Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 16: expected str for dictionary value 'option1', got 123.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 21: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", + 'message': "Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 21: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 29: required key 'option1' not provided. - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 30: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 31: expected str for dictionary value 'option2', got 123. + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 29: required key 'option1' not provided. + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 30: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 31: expected str for dictionary value 'option2', got 123. ''', }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_2] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 38: required key 'host' not provided.", + 'message': "Invalid config for [adr_0007_2] at configuration.yaml, line 38: required key 'host' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_3] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 43: expected int for dictionary value 'adr_0007_3->port', got 'foo'.", + 'message': "Invalid config for [adr_0007_3] at configuration.yaml, line 43: expected int for dictionary value 'adr_0007_3->port', got 'foo'.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_4] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 48: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option", + 'message': "Invalid config for [adr_0007_4] at configuration.yaml, line 48: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 54: required key 'host' not provided. - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 55: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 56: expected int for dictionary value 'adr_0007_5->port', got 'foo'. + Invalid config for [adr_0007_5] at configuration.yaml, line 54: required key 'host' not provided. + Invalid config for [adr_0007_5] at configuration.yaml, line 55: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option + Invalid config for [adr_0007_5] at configuration.yaml, line 56: expected int for dictionary value 'adr_0007_5->port', got 'foo'. ''', }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [custom_validator_ok_2] at /fixtures/core/config/component_validation/packages/configuration.yaml, line 64: required key 'host' not provided.", + 'message': "Invalid config for [custom_validator_ok_2] at configuration.yaml, line 64: required key 'host' not provided.", }), dict({ 'has_exc_info': True, @@ -235,47 +235,47 @@ list([ dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/iot_domain.yaml, line 6: required key 'platform' not provided.", + 'message': "Invalid config for [iot_domain] at integrations/iot_domain.yaml, line 6: required key 'platform' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/iot_domain.yaml, line 9: expected str for dictionary value 'option1', got 123.", + 'message': "Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 9: expected str for dictionary value 'option1', got 123.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/iot_domain.yaml, line 12: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", + 'message': "Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 12: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/iot_domain.yaml, line 18: required key 'option1' not provided. - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/iot_domain.yaml, line 19: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/iot_domain.yaml, line 20: expected str for dictionary value 'option2', got 123. + Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 18: required key 'option1' not provided. + Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 19: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option + Invalid config for [iot_domain.non_adr_0007] at integrations/iot_domain.yaml, line 20: expected str for dictionary value 'option2', got 123. ''', }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_2] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/adr_0007_2.yaml, line 2: required key 'host' not provided.", + 'message': "Invalid config for [adr_0007_2] at integrations/adr_0007_2.yaml, line 2: required key 'host' not provided.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_3] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/adr_0007_3.yaml, line 4: expected int for dictionary value 'adr_0007_3->port', got 'foo'.", + 'message': "Invalid config for [adr_0007_3] at integrations/adr_0007_3.yaml, line 4: expected int for dictionary value 'adr_0007_3->port', got 'foo'.", }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [adr_0007_4] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/adr_0007_4.yaml, line 4: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option", + 'message': "Invalid config for [adr_0007_4] at integrations/adr_0007_4.yaml, line 4: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option", }), dict({ 'has_exc_info': False, 'message': ''' - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/adr_0007_5.yaml, line 5: required key 'host' not provided. - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/adr_0007_5.yaml, line 6: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/adr_0007_5.yaml, line 7: expected int for dictionary value 'adr_0007_5->port', got 'foo'. + Invalid config for [adr_0007_5] at integrations/adr_0007_5.yaml, line 5: required key 'host' not provided. + Invalid config for [adr_0007_5] at integrations/adr_0007_5.yaml, line 6: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option + Invalid config for [adr_0007_5] at integrations/adr_0007_5.yaml, line 7: expected int for dictionary value 'adr_0007_5->port', got 'foo'. ''', }), dict({ 'has_exc_info': False, - 'message': "Invalid config for [custom_validator_ok_2] at /fixtures/core/config/component_validation/packages_include_dir_named/integrations/custom_validator_ok_2.yaml, line 2: required key 'host' not provided.", + 'message': "Invalid config for [custom_validator_ok_2] at integrations/custom_validator_ok_2.yaml, line 2: required key 'host' not provided.", }), dict({ 'has_exc_info': True, @@ -289,61 +289,61 @@ # --- # name: test_component_config_validation_error_with_docs[basic] list([ - "Invalid config for [iot_domain] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 6: required key 'platform' not provided. Please check the docs at https://www.home-assistant.io/integrations/iot_domain.", - "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 9: expected str for dictionary value 'option1', got 123. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007.", - "Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 12: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007", + "Invalid config for [iot_domain] at configuration.yaml, line 6: required key 'platform' not provided. Please check the docs at https://www.home-assistant.io/integrations/iot_domain.", + "Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 9: expected str for dictionary value 'option1', got 123. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007.", + "Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 12: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007", ''' - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 18: required key 'option1' not provided. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007. - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 19: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007 - Invalid config for [iot_domain.non_adr_0007] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 20: expected str for dictionary value 'option2', got 123. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007. + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 18: required key 'option1' not provided. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007. + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 19: 'no_such_option' is an invalid option for [iot_domain.non_adr_0007], check: no_such_option. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007 + Invalid config for [iot_domain.non_adr_0007] at configuration.yaml, line 20: expected str for dictionary value 'option2', got 123. Please check the docs at https://www.home-assistant.io/integrations/non_adr_0007. ''', - "Invalid config for [adr_0007_2] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 27: required key 'host' not provided. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_2.", - "Invalid config for [adr_0007_3] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 32: expected int for dictionary value 'adr_0007_3->port', got 'foo'. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_3.", - "Invalid config for [adr_0007_4] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 37: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_4", + "Invalid config for [adr_0007_2] at configuration.yaml, line 27: required key 'host' not provided. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_2.", + "Invalid config for [adr_0007_3] at configuration.yaml, line 32: expected int for dictionary value 'adr_0007_3->port', got 'foo'. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_3.", + "Invalid config for [adr_0007_4] at configuration.yaml, line 37: 'no_such_option' is an invalid option for [adr_0007_4], check: adr_0007_4->no_such_option. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_4", ''' - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 43: required key 'host' not provided. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_5. - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 44: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_5 - Invalid config for [adr_0007_5] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 45: expected int for dictionary value 'adr_0007_5->port', got 'foo'. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_5. + Invalid config for [adr_0007_5] at configuration.yaml, line 43: required key 'host' not provided. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_5. + Invalid config for [adr_0007_5] at configuration.yaml, line 44: 'no_such_option' is an invalid option for [adr_0007_5], check: adr_0007_5->no_such_option. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_5 + Invalid config for [adr_0007_5] at configuration.yaml, line 45: expected int for dictionary value 'adr_0007_5->port', got 'foo'. Please check the docs at https://www.home-assistant.io/integrations/adr_0007_5. ''', - "Invalid config for [custom_validator_ok_2] at /fixtures/core/config/component_validation/basic/configuration.yaml, line 52: required key 'host' not provided. Please check the docs at https://www.home-assistant.io/integrations/custom_validator_ok_2.", + "Invalid config for [custom_validator_ok_2] at configuration.yaml, line 52: required key 'host' not provided. Please check the docs at https://www.home-assistant.io/integrations/custom_validator_ok_2.", 'Invalid config for [custom_validator_bad_1]: broken Please check the docs at https://www.home-assistant.io/integrations/custom_validator_bad_1.', 'Unknown error calling custom_validator_bad_2 config validator', ]) # --- # name: test_package_merge_error[packages] list([ - 'Package pack_1 setup failed. Integration adr_0007_1 cannot be merged. Dict expected in main config. (See /fixtures/core/config/package_errors/packages/configuration.yaml:9).', - 'Package pack_2 setup failed. Integration adr_0007_2 cannot be merged. Expected a dict. (See /fixtures/core/config/package_errors/packages/configuration.yaml:13).', - "Package pack_4 setup failed. Integration adr_0007_3 has duplicate key 'host'. (See /fixtures/core/config/package_errors/packages/configuration.yaml:20).", - "Package pack_5 setup failed. Integration 'unknown_integration' not found. (See /fixtures/core/config/package_errors/packages/configuration.yaml:23).", + 'Package pack_1 setup failed. Integration adr_0007_1 cannot be merged. Dict expected in main config. (See configuration.yaml:9).', + 'Package pack_2 setup failed. Integration adr_0007_2 cannot be merged. Expected a dict. (See configuration.yaml:13).', + "Package pack_4 setup failed. Integration adr_0007_3 has duplicate key 'host'. (See configuration.yaml:20).", + "Package pack_5 setup failed. Integration 'unknown_integration' not found. (See configuration.yaml:23).", ]) # --- # name: test_package_merge_error[packages_include_dir_named] list([ - 'Package adr_0007_1 setup failed. Integration adr_0007_1 cannot be merged. Dict expected in main config. (See /fixtures/core/config/package_errors/packages_include_dir_named/integrations/adr_0007_1.yaml:2).', - 'Package adr_0007_2 setup failed. Integration adr_0007_2 cannot be merged. Expected a dict. (See /fixtures/core/config/package_errors/packages_include_dir_named/integrations/adr_0007_2.yaml:2).', - "Package adr_0007_3_2 setup failed. Integration adr_0007_3 has duplicate key 'host'. (See /fixtures/core/config/package_errors/packages_include_dir_named/integrations/adr_0007_3_2.yaml:1).", - "Package unknown_integration setup failed. Integration 'unknown_integration' not found. (See /fixtures/core/config/package_errors/packages_include_dir_named/integrations/unknown_integration.yaml:2).", + 'Package adr_0007_1 setup failed. Integration adr_0007_1 cannot be merged. Dict expected in main config. (See integrations/adr_0007_1.yaml:2).', + 'Package adr_0007_2 setup failed. Integration adr_0007_2 cannot be merged. Expected a dict. (See integrations/adr_0007_2.yaml:2).', + "Package adr_0007_3_2 setup failed. Integration adr_0007_3 has duplicate key 'host'. (See integrations/adr_0007_3_2.yaml:1).", + "Package unknown_integration setup failed. Integration 'unknown_integration' not found. (See integrations/unknown_integration.yaml:2).", ]) # --- # name: test_package_merge_exception[packages-error0] list([ - "Package pack_1 setup failed. Integration test_domain caused error: No such file or directory: b'liblibc.a' (See /fixtures/core/config/package_exceptions/packages/configuration.yaml:4).", + "Package pack_1 setup failed. Integration test_domain caused error: No such file or directory: b'liblibc.a' (See configuration.yaml:4).", ]) # --- # name: test_package_merge_exception[packages-error1] list([ - "Package pack_1 setup failed. Integration test_domain caused error: ModuleNotFoundError: No module named 'not_installed_something' (See /fixtures/core/config/package_exceptions/packages/configuration.yaml:4).", + "Package pack_1 setup failed. Integration test_domain caused error: ModuleNotFoundError: No module named 'not_installed_something' (See configuration.yaml:4).", ]) # --- # name: test_package_merge_exception[packages_include_dir_named-error0] list([ - "Package unknown_integration setup failed. Integration test_domain caused error: No such file or directory: b'liblibc.a' (See /fixtures/core/config/package_exceptions/packages_include_dir_named/integrations/unknown_integration.yaml:1).", + "Package unknown_integration setup failed. Integration test_domain caused error: No such file or directory: b'liblibc.a' (See integrations/unknown_integration.yaml:1).", ]) # --- # name: test_package_merge_exception[packages_include_dir_named-error1] list([ - "Package unknown_integration setup failed. Integration test_domain caused error: ModuleNotFoundError: No module named 'not_installed_something' (See /fixtures/core/config/package_exceptions/packages_include_dir_named/integrations/unknown_integration.yaml:1).", + "Package unknown_integration setup failed. Integration test_domain caused error: ModuleNotFoundError: No module named 'not_installed_something' (See integrations/unknown_integration.yaml:1).", ]) # --- # name: test_yaml_error[basic] diff --git a/tests/test_config.py b/tests/test_config.py index dab8243bb39..8d74d53c162 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1730,7 +1730,7 @@ async def test_component_config_validation_error( error_records = [ { - "message": record.message.replace(base_path, ""), + "message": record.message, "has_exc_info": bool(record.exc_info), } for record in caplog.get_records("call") @@ -1783,7 +1783,7 @@ async def test_component_config_validation_error_with_docs( ) error_records = [ - record.message.replace(base_path, "") + record.message for record in caplog.get_records("call") if record.levelno == logging.ERROR ] @@ -1811,7 +1811,7 @@ async def test_package_merge_error( await config_util.async_hass_config_yaml(hass) error_records = [ - record.message.replace(base_path, "") + record.message for record in caplog.get_records("call") if record.levelno == logging.ERROR ] @@ -1851,7 +1851,7 @@ async def test_package_merge_exception( await config_util.async_hass_config_yaml(hass) error_records = [ - record.message.replace(base_path, "") + record.message for record in caplog.get_records("call") if record.levelno == logging.ERROR ]