mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Migrate integration_platform helper to use async_get_integrations (#89303)
* Migrate integration_platform helper to use async_get_integrations We were fetching integrations inside the gather one at a time. This is inefficent. * cleanup * cleanup * add task name * small tweaks * gather only if we have tasks
This commit is contained in:
parent
4f11344bc3
commit
e1d62b554a
@ -8,8 +8,8 @@ import logging
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.const import EVENT_COMPONENT_LOADED
|
from homeassistant.const import EVENT_COMPONENT_LOADED
|
||||||
from homeassistant.core import Event, HomeAssistant
|
from homeassistant.core import Event, HomeAssistant, callback
|
||||||
from homeassistant.loader import async_get_integration, bind_hass
|
from homeassistant.loader import Integration, async_get_integrations, bind_hass
|
||||||
from homeassistant.setup import ATTR_COMPONENT
|
from homeassistant.setup import ATTR_COMPONENT
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -26,14 +26,24 @@ class IntegrationPlatform:
|
|||||||
|
|
||||||
|
|
||||||
async def _async_process_single_integration_platform_component(
|
async def _async_process_single_integration_platform_component(
|
||||||
hass: HomeAssistant, component_name: str, integration_platform: IntegrationPlatform
|
hass: HomeAssistant,
|
||||||
|
component_name: str,
|
||||||
|
integration: Integration | Exception,
|
||||||
|
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)
|
||||||
|
|
||||||
integration = await async_get_integration(hass, component_name)
|
if isinstance(integration, Exception):
|
||||||
|
_LOGGER.exception(
|
||||||
|
"Error importing integration %s for %s",
|
||||||
|
component_name,
|
||||||
|
integration_platform.platform_name,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
platform_name = integration_platform.platform_name
|
platform_name = integration_platform.platform_name
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -75,14 +85,22 @@ async def async_process_integration_platform_for_component(
|
|||||||
integration_platforms: list[IntegrationPlatform] = hass.data[
|
integration_platforms: list[IntegrationPlatform] = hass.data[
|
||||||
DATA_INTEGRATION_PLATFORMS
|
DATA_INTEGRATION_PLATFORMS
|
||||||
]
|
]
|
||||||
await asyncio.gather(
|
integrations = await async_get_integrations(hass, (component_name,))
|
||||||
*[
|
tasks = [
|
||||||
|
asyncio.create_task(
|
||||||
_async_process_single_integration_platform_component(
|
_async_process_single_integration_platform_component(
|
||||||
hass, component_name, integration_platform
|
hass,
|
||||||
)
|
component_name,
|
||||||
for integration_platform in integration_platforms
|
integrations[component_name],
|
||||||
]
|
integration_platform,
|
||||||
)
|
),
|
||||||
|
name=f"process integration platform {integration_platform.platform_name} for {component_name}",
|
||||||
|
)
|
||||||
|
for integration_platform in integration_platforms
|
||||||
|
if component_name not in integration_platform.seen_components
|
||||||
|
]
|
||||||
|
if tasks:
|
||||||
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
|
||||||
@bind_hass
|
@bind_hass
|
||||||
@ -98,25 +116,39 @@ async def async_process_integration_platforms(
|
|||||||
|
|
||||||
async def _async_component_loaded(event: Event) -> None:
|
async def _async_component_loaded(event: Event) -> None:
|
||||||
"""Handle a new component loaded."""
|
"""Handle a new component loaded."""
|
||||||
comp = event.data[ATTR_COMPONENT]
|
await async_process_integration_platform_for_component(
|
||||||
if "." not in comp:
|
hass, event.data[ATTR_COMPONENT]
|
||||||
await async_process_integration_platform_for_component(hass, comp)
|
)
|
||||||
|
|
||||||
hass.bus.async_listen(EVENT_COMPONENT_LOADED, _async_component_loaded)
|
@callback
|
||||||
|
def _async_component_loaded_filter(event: Event) -> bool:
|
||||||
|
"""Handle integration platforms loaded."""
|
||||||
|
return "." not in event.data[ATTR_COMPONENT]
|
||||||
|
|
||||||
|
hass.bus.async_listen(
|
||||||
|
EVENT_COMPONENT_LOADED,
|
||||||
|
_async_component_loaded,
|
||||||
|
event_filter=_async_component_loaded_filter,
|
||||||
|
)
|
||||||
|
|
||||||
integration_platforms: list[IntegrationPlatform] = hass.data[
|
integration_platforms: list[IntegrationPlatform] = hass.data[
|
||||||
DATA_INTEGRATION_PLATFORMS
|
DATA_INTEGRATION_PLATFORMS
|
||||||
]
|
]
|
||||||
integration_platform = IntegrationPlatform(platform_name, process_platform, set())
|
integration_platform = IntegrationPlatform(platform_name, process_platform, set())
|
||||||
integration_platforms.append(integration_platform)
|
integration_platforms.append(integration_platform)
|
||||||
if top_level_components := (
|
if top_level_components := [
|
||||||
comp for comp in hass.config.components if "." not in comp
|
comp for comp in hass.config.components if "." not in comp
|
||||||
):
|
]:
|
||||||
await asyncio.gather(
|
integrations = await async_get_integrations(hass, top_level_components)
|
||||||
*[
|
tasks = [
|
||||||
|
asyncio.create_task(
|
||||||
_async_process_single_integration_platform_component(
|
_async_process_single_integration_platform_component(
|
||||||
hass, comp, integration_platform
|
hass, comp, integrations[comp], integration_platform
|
||||||
)
|
),
|
||||||
for comp in top_level_components
|
name=f"process integration platform {platform_name} for {comp}",
|
||||||
]
|
)
|
||||||
)
|
for comp in top_level_components
|
||||||
|
if comp not in integration_platform.seen_components
|
||||||
|
]
|
||||||
|
if tasks:
|
||||||
|
await asyncio.gather(*tasks)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
"""Test integration platform helpers."""
|
"""Test integration platform helpers."""
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.integration_platform import (
|
from homeassistant.helpers.integration_platform import (
|
||||||
async_process_integration_platform_for_component,
|
async_process_integration_platform_for_component,
|
||||||
@ -51,3 +53,27 @@ async def test_process_integration_platforms_none_loaded(hass: HomeAssistant) ->
|
|||||||
# Verify we can call async_process_integration_platform_for_component
|
# Verify we can call async_process_integration_platform_for_component
|
||||||
# when there are none loaded and it does not throw
|
# when there are none loaded and it does not throw
|
||||||
await async_process_integration_platform_for_component(hass, "any")
|
await async_process_integration_platform_for_component(hass, "any")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_broken_integration(
|
||||||
|
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||||
|
) -> None:
|
||||||
|
"""Test handling an integration with a broken or missing manifest."""
|
||||||
|
Mock()
|
||||||
|
hass.config.components.add("loaded")
|
||||||
|
|
||||||
|
event_platform = Mock()
|
||||||
|
mock_platform(hass, "event.platform_to_check", event_platform)
|
||||||
|
|
||||||
|
processed = []
|
||||||
|
|
||||||
|
async def _process_platform(hass, domain, platform):
|
||||||
|
"""Process platform."""
|
||||||
|
processed.append((domain, platform))
|
||||||
|
|
||||||
|
await async_process_integration_platforms(
|
||||||
|
hass, "platform_to_check", _process_platform
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(processed) == 0
|
||||||
|
assert "Error importing integration loaded for platform_to_check" in caplog.text
|
||||||
|
Loading…
x
Reference in New Issue
Block a user