mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Speed up async_get_loaded_integrations (#117851)
* Speed up async_get_loaded_integrations Use a setcomp and difference to find the components to split to avoid the loop. A setcomp is inlined in python3.12 so its much faster * Speed up async_get_loaded_integrations Use a setcomp and difference to find the components to split to avoid the loop. A setcomp is inlined in python3.12 so its much faster * simplify * fix compat * bootstrap * fix tests
This commit is contained in:
parent
266ce9e268
commit
e12d23bd48
@ -63,6 +63,7 @@ from .components import (
|
|||||||
)
|
)
|
||||||
from .components.sensor import recorder as sensor_recorder # noqa: F401
|
from .components.sensor import recorder as sensor_recorder # noqa: F401
|
||||||
from .const import (
|
from .const import (
|
||||||
|
BASE_PLATFORMS,
|
||||||
FORMAT_DATETIME,
|
FORMAT_DATETIME,
|
||||||
KEY_DATA_LOGGING as DATA_LOGGING,
|
KEY_DATA_LOGGING as DATA_LOGGING,
|
||||||
REQUIRED_NEXT_PYTHON_HA_RELEASE,
|
REQUIRED_NEXT_PYTHON_HA_RELEASE,
|
||||||
@ -90,7 +91,6 @@ from .helpers.storage import get_internal_store_manager
|
|||||||
from .helpers.system_info import async_get_system_info
|
from .helpers.system_info import async_get_system_info
|
||||||
from .helpers.typing import ConfigType
|
from .helpers.typing import ConfigType
|
||||||
from .setup import (
|
from .setup import (
|
||||||
BASE_PLATFORMS,
|
|
||||||
# _setup_started is marked as protected to make it clear
|
# _setup_started is marked as protected to make it clear
|
||||||
# that it is not part of the public API and should not be used
|
# that it is not part of the public API and should not be used
|
||||||
# by integrations. It is only used for internal tracking of
|
# by integrations. It is only used for internal tracking of
|
||||||
|
@ -83,6 +83,9 @@ class Platform(StrEnum):
|
|||||||
WEATHER = "weather"
|
WEATHER = "weather"
|
||||||
|
|
||||||
|
|
||||||
|
BASE_PLATFORMS: Final = {platform.value for platform in Platform}
|
||||||
|
|
||||||
|
|
||||||
# Can be used to specify a catch all when registering state or event listeners.
|
# Can be used to specify a catch all when registering state or event listeners.
|
||||||
MATCH_ALL: Final = "*"
|
MATCH_ALL: Final = "*"
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ from .const import (
|
|||||||
ATTR_FRIENDLY_NAME,
|
ATTR_FRIENDLY_NAME,
|
||||||
ATTR_SERVICE,
|
ATTR_SERVICE,
|
||||||
ATTR_SERVICE_DATA,
|
ATTR_SERVICE_DATA,
|
||||||
|
BASE_PLATFORMS,
|
||||||
COMPRESSED_STATE_ATTRIBUTES,
|
COMPRESSED_STATE_ATTRIBUTES,
|
||||||
COMPRESSED_STATE_CONTEXT,
|
COMPRESSED_STATE_CONTEXT,
|
||||||
COMPRESSED_STATE_LAST_CHANGED,
|
COMPRESSED_STATE_LAST_CHANGED,
|
||||||
@ -2769,16 +2770,27 @@ class _ComponentSet(set[str]):
|
|||||||
|
|
||||||
The top level components set only contains the top level components.
|
The top level components set only contains the top level components.
|
||||||
|
|
||||||
|
The all components set contains all components, including platform
|
||||||
|
based components.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, top_level_components: set[str]) -> None:
|
def __init__(
|
||||||
|
self, top_level_components: set[str], all_components: set[str]
|
||||||
|
) -> None:
|
||||||
"""Initialize the component set."""
|
"""Initialize the component set."""
|
||||||
self._top_level_components = top_level_components
|
self._top_level_components = top_level_components
|
||||||
|
self._all_components = all_components
|
||||||
|
|
||||||
def add(self, component: str) -> None:
|
def add(self, component: str) -> None:
|
||||||
"""Add a component to the store."""
|
"""Add a component to the store."""
|
||||||
if "." not in component:
|
if "." not in component:
|
||||||
self._top_level_components.add(component)
|
self._top_level_components.add(component)
|
||||||
|
self._all_components.add(component)
|
||||||
|
else:
|
||||||
|
platform, _, domain = component.partition(".")
|
||||||
|
if domain in BASE_PLATFORMS:
|
||||||
|
self._all_components.add(platform)
|
||||||
return super().add(component)
|
return super().add(component)
|
||||||
|
|
||||||
def remove(self, component: str) -> None:
|
def remove(self, component: str) -> None:
|
||||||
@ -2831,8 +2843,14 @@ class Config:
|
|||||||
# and should not be modified directly
|
# and should not be modified directly
|
||||||
self.top_level_components: set[str] = set()
|
self.top_level_components: set[str] = set()
|
||||||
|
|
||||||
|
# Set of all loaded components including platform
|
||||||
|
# based components
|
||||||
|
self.all_components: set[str] = set()
|
||||||
|
|
||||||
# Set of loaded components
|
# Set of loaded components
|
||||||
self.components: _ComponentSet = _ComponentSet(self.top_level_components)
|
self.components: _ComponentSet = _ComponentSet(
|
||||||
|
self.top_level_components, self.all_components
|
||||||
|
)
|
||||||
|
|
||||||
# API (HTTP) server configuration
|
# API (HTTP) server configuration
|
||||||
self.api: ApiConfig | None = None
|
self.api: ApiConfig | None = None
|
||||||
|
@ -16,10 +16,10 @@ from typing import Any, Final, TypedDict
|
|||||||
|
|
||||||
from . import config as conf_util, core, loader, requirements
|
from . import config as conf_util, core, loader, requirements
|
||||||
from .const import (
|
from .const import (
|
||||||
|
BASE_PLATFORMS, # noqa: F401
|
||||||
EVENT_COMPONENT_LOADED,
|
EVENT_COMPONENT_LOADED,
|
||||||
EVENT_HOMEASSISTANT_START,
|
EVENT_HOMEASSISTANT_START,
|
||||||
PLATFORM_FORMAT,
|
PLATFORM_FORMAT,
|
||||||
Platform,
|
|
||||||
)
|
)
|
||||||
from .core import (
|
from .core import (
|
||||||
CALLBACK_TYPE,
|
CALLBACK_TYPE,
|
||||||
@ -44,7 +44,6 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
ATTR_COMPONENT: Final = "component"
|
ATTR_COMPONENT: Final = "component"
|
||||||
|
|
||||||
BASE_PLATFORMS = {platform.value for platform in Platform}
|
|
||||||
|
|
||||||
# DATA_SETUP is a dict, indicating domains which are currently
|
# DATA_SETUP is a dict, indicating domains which are currently
|
||||||
# being setup or which failed to setup:
|
# being setup or which failed to setup:
|
||||||
@ -637,15 +636,7 @@ def _async_when_setup(
|
|||||||
@core.callback
|
@core.callback
|
||||||
def async_get_loaded_integrations(hass: core.HomeAssistant) -> set[str]:
|
def async_get_loaded_integrations(hass: core.HomeAssistant) -> set[str]:
|
||||||
"""Return the complete list of loaded integrations."""
|
"""Return the complete list of loaded integrations."""
|
||||||
integrations = set()
|
return hass.config.all_components
|
||||||
for component in hass.config.components:
|
|
||||||
if "." not in component:
|
|
||||||
integrations.add(component)
|
|
||||||
continue
|
|
||||||
platform, _, domain = component.partition(".")
|
|
||||||
if domain in BASE_PLATFORMS:
|
|
||||||
integrations.add(platform)
|
|
||||||
return integrations
|
|
||||||
|
|
||||||
|
|
||||||
class SetupPhases(StrEnum):
|
class SetupPhases(StrEnum):
|
||||||
|
@ -246,7 +246,7 @@ async def test_send_usage(
|
|||||||
|
|
||||||
assert analytics.preferences[ATTR_BASE]
|
assert analytics.preferences[ATTR_BASE]
|
||||||
assert analytics.preferences[ATTR_USAGE]
|
assert analytics.preferences[ATTR_USAGE]
|
||||||
hass.config.components = ["default_config"]
|
hass.config.components.add("default_config")
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.config.load_yaml_config_file",
|
"homeassistant.config.load_yaml_config_file",
|
||||||
@ -280,7 +280,7 @@ async def test_send_usage_with_supervisor(
|
|||||||
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
||||||
assert analytics.preferences[ATTR_BASE]
|
assert analytics.preferences[ATTR_BASE]
|
||||||
assert analytics.preferences[ATTR_USAGE]
|
assert analytics.preferences[ATTR_USAGE]
|
||||||
hass.config.components = ["default_config"]
|
hass.config.components.add("default_config")
|
||||||
|
|
||||||
with (
|
with (
|
||||||
patch(
|
patch(
|
||||||
@ -344,7 +344,7 @@ async def test_send_statistics(
|
|||||||
await analytics.save_preferences({ATTR_BASE: True, ATTR_STATISTICS: True})
|
await analytics.save_preferences({ATTR_BASE: True, ATTR_STATISTICS: True})
|
||||||
assert analytics.preferences[ATTR_BASE]
|
assert analytics.preferences[ATTR_BASE]
|
||||||
assert analytics.preferences[ATTR_STATISTICS]
|
assert analytics.preferences[ATTR_STATISTICS]
|
||||||
hass.config.components = ["default_config"]
|
hass.config.components.add("default_config")
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.config.load_yaml_config_file",
|
"homeassistant.config.load_yaml_config_file",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user