Skip to content
Snippets Groups Projects
Unverified Commit 5e79cd87 authored by Erik Montnemery's avatar Erik Montnemery Committed by GitHub
Browse files

Remove file/line annotations after config has been validated (#107139)

parent 7fc3f8e4
No related branches found
No related tags found
No related merge requests found
......@@ -14,7 +14,7 @@ from pathlib import Path
import re
import shutil
from types import ModuleType
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, TypeVar
from urllib.parse import urlparse
from awesomeversion import AwesomeVersion
......@@ -67,6 +67,7 @@ from .requirements import RequirementsNotFound, async_get_integration_with_requi
from .util.package import is_docker_env
from .util.unit_system import get_unit_system, validate_unit_system
from .util.yaml import SECRET_YAML, Secrets, YamlTypeError, load_yaml_dict
from .util.yaml.objects import NodeStrClass
_LOGGER = logging.getLogger(__name__)
......@@ -146,6 +147,9 @@ class ConfigExceptionInfo:
integration_link: str | None
_T = TypeVar("_T")
@dataclass
class IntegrationConfigInfo:
"""Configuration for an integration and exception information."""
......@@ -1221,9 +1225,45 @@ async def async_process_component_and_handle_errors(
integration_config_info = await async_process_component_config(
hass, config, integration
)
return async_handle_component_errors(
async_handle_component_errors(
hass, integration_config_info, integration, raise_on_failure
)
return async_drop_config_annotations(integration_config_info, integration)
@callback
def async_drop_config_annotations(
integration_config_info: IntegrationConfigInfo,
integration: Integration,
) -> ConfigType | None:
"""Remove file and line annotations from str items in component configuration."""
if (config := integration_config_info.config) is None:
return None
def drop_config_annotations_rec(node: Any) -> Any:
if isinstance(node, dict):
# Some integrations store metadata in custom dict classes, preserve those
tmp = dict(node)
node.clear()
node.update(
(drop_config_annotations_rec(k), drop_config_annotations_rec(v))
for k, v in tmp.items()
)
return node
if isinstance(node, list):
return [drop_config_annotations_rec(v) for v in node]
if isinstance(node, NodeStrClass):
return str(node)
return node
# Don't drop annotations from the homeassistant integration because it may
# have configuration for other integrations as packages.
if integration.domain in config and integration.domain != CONF_CORE:
drop_config_annotations_rec(config[integration.domain])
return config
@callback
......@@ -1232,18 +1272,16 @@ def async_handle_component_errors(
integration_config_info: IntegrationConfigInfo,
integration: Integration,
raise_on_failure: bool = False,
) -> ConfigType | None:
) -> None:
"""Handle component configuration errors from async_process_component_config.
In case of errors:
- Print the error messages to the log.
- Raise a ConfigValidationError if raise_on_failure is set.
Returns the integration config or `None`.
"""
if not (config_exception_info := integration_config_info.exception_info_list):
return integration_config_info.config
return
platform_exception: ConfigExceptionInfo
domain = integration.domain
......@@ -1261,7 +1299,7 @@ def async_handle_component_errors(
)
if not raise_on_failure:
return integration_config_info.config
return
if len(config_exception_info) == 1:
translation_key = platform_exception.translation_key
......
......@@ -256,8 +256,9 @@ async def _async_setup_component(
integration_config_info = await conf_util.async_process_component_config(
hass, config, integration
)
processed_config = conf_util.async_handle_component_errors(
hass, integration_config_info, integration
conf_util.async_handle_component_errors(hass, integration_config_info, integration)
processed_config = conf_util.async_drop_config_annotations(
integration_config_info, integration
)
for platform_exception in integration_config_info.exception_info_list:
if platform_exception.translation_key not in NOTIFY_FOR_TRANSLATION_KEYS:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment