Avoid creating tasks to load integration platforms that do not exist (#110743)

This commit is contained in:
J. Nick Koston 2024-02-17 07:02:51 -06:00 committed by GitHub
parent df3556f0d8
commit 42cf081582
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -5,6 +5,7 @@ import asyncio
from collections.abc import Awaitable, Callable from collections.abc import Awaitable, Callable
from dataclasses import dataclass from dataclasses import dataclass
import logging import logging
from types import ModuleType
from typing import Any from typing import Any
from homeassistant.const import EVENT_COMPONENT_LOADED from homeassistant.const import EVENT_COMPONENT_LOADED
@ -28,26 +29,37 @@ class IntegrationPlatform:
async def _async_process_single_integration_platform_component( async def _async_process_single_integration_platform_component(
hass: HomeAssistant, hass: HomeAssistant,
component_name: str, component_name: str,
integration: Integration | Exception, platform: ModuleType,
integration_platform: IntegrationPlatform, integration_platform: IntegrationPlatform,
) -> None: ) -> None:
"""Process a single integration platform.""" """Process a single integration platform."""
if component_name in integration_platform.seen_components: if component_name in integration_platform.seen_components:
return return
integration_platform.seen_components.add(component_name) integration_platform.seen_components.add(component_name)
try:
await integration_platform.process_platform(hass, component_name, platform)
except Exception: # pylint: disable=broad-except
_LOGGER.exception(
"Error processing platform %s.%s",
component_name,
integration_platform.platform_name,
)
def _get_platform_from_integration(
integration: Integration | Exception, component_name: str, platform_name: str
) -> ModuleType | None:
"""Get a platform from an integration."""
if isinstance(integration, Exception): if isinstance(integration, Exception):
_LOGGER.exception( _LOGGER.exception(
"Error importing integration %s for %s", "Error importing integration %s for %s",
component_name, component_name,
integration_platform.platform_name, platform_name,
) )
return return None
platform_name = integration_platform.platform_name
try: try:
platform = integration.get_platform(platform_name) return integration.get_platform(platform_name)
except ImportError as err: except ImportError as err:
if f"{component_name}.{platform_name}" not in str(err): if f"{component_name}.{platform_name}" not in str(err):
_LOGGER.exception( _LOGGER.exception(
@ -55,14 +67,8 @@ async def _async_process_single_integration_platform_component(
component_name, component_name,
platform_name, platform_name,
) )
return
try: return None
await integration_platform.process_platform(hass, component_name, platform)
except Exception: # pylint: disable=broad-except
_LOGGER.exception(
"Error processing platform %s.%s", component_name, platform_name
)
async def _async_process_integration_platform_for_component( async def _async_process_integration_platform_for_component(
@ -78,13 +84,20 @@ async def _async_process_integration_platform_for_component(
_async_process_single_integration_platform_component( _async_process_single_integration_platform_component(
hass, hass,
component_name, component_name,
integrations[component_name], platform,
integration_platform, integration_platform,
), ),
name=f"process integration platform {integration_platform.platform_name} for {component_name}", name=f"process integration platform {integration_platform.platform_name} for {component_name}",
) )
for integration_platform in integration_platforms for integration_platform in integration_platforms
if component_name not in integration_platform.seen_components if component_name not in integration_platform.seen_components
and (
platform := _get_platform_from_integration(
integrations[component_name],
component_name,
integration_platform.platform_name,
)
)
] ]
if tasks: if tasks:
await asyncio.gather(*tasks) await asyncio.gather(*tasks)
@ -130,12 +143,17 @@ async def async_process_integration_platforms(
tasks = [ tasks = [
asyncio.create_task( asyncio.create_task(
_async_process_single_integration_platform_component( _async_process_single_integration_platform_component(
hass, comp, integrations[comp], integration_platform hass, comp, platform, integration_platform
), ),
name=f"process integration platform {platform_name} for {comp}", name=f"process integration platform {platform_name} for {comp}",
) )
for comp in top_level_components for comp in top_level_components
if comp not in integration_platform.seen_components if comp not in integration_platform.seen_components
and (
platform := _get_platform_from_integration(
integrations[comp], comp, platform_name
)
)
] ]
if tasks: if tasks:
await asyncio.gather(*tasks) await asyncio.gather(*tasks)