Skip to content

Commit

Permalink
Use HassKey for setup keys
Browse files Browse the repository at this point in the history
  • Loading branch information
cdce8p committed Apr 29, 2024
1 parent 411a3a4 commit 5d053ea
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 33 deletions.
4 changes: 1 addition & 3 deletions homeassistant/config_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -2026,9 +2026,7 @@ async def async_wait_component(self, entry: ConfigEntry) -> bool:
Config entries which are created after Home Assistant is started can't be waited
for, the function will just return if the config entry is loaded or not.
"""
setup_done: dict[str, asyncio.Future[bool]] = self.hass.data.get(
DATA_SETUP_DONE, {}
)
setup_done = self.hass.data.get(DATA_SETUP_DONE, {})
if setup_future := setup_done.get(entry.domain):
await setup_future
# The component was not loaded.
Expand Down
42 changes: 19 additions & 23 deletions homeassistant/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from .helpers.issue_registry import IssueSeverity, async_create_issue
from .helpers.typing import ConfigType
from .util.async_ import create_eager_task
from .util.hass_dict import HassKey

current_setup_group: contextvars.ContextVar[tuple[str, str | None] | None] = (
contextvars.ContextVar("current_setup_group", default=None)
Expand All @@ -45,29 +46,32 @@

BASE_PLATFORMS = {platform.value for platform in Platform}

# DATA_SETUP is a dict[str, asyncio.Future[bool]], indicating domains which are currently
# DATA_SETUP is a dict, indicating domains which are currently
# being setup or which failed to setup:
# - Tasks are added to DATA_SETUP by `async_setup_component`, the key is the domain
# being setup and the Task is the `_async_setup_component` helper.
# - Tasks are removed from DATA_SETUP if setup was successful, that is,
# the task returned True.
DATA_SETUP = "setup_tasks"
DATA_SETUP: HassKey[dict[str, asyncio.Future[bool]]] = HassKey("setup_tasks")

# DATA_SETUP_DONE is a dict [str, asyncio.Future[bool]], indicating components which
# will be setup:
# DATA_SETUP_DONE is a dict, indicating components which will be setup:
# - Events are added to DATA_SETUP_DONE during bootstrap by
# async_set_domains_to_be_loaded, the key is the domain which will be loaded.
# - Events are set and removed from DATA_SETUP_DONE when async_setup_component
# is finished, regardless of if the setup was successful or not.
DATA_SETUP_DONE = "setup_done"
DATA_SETUP_DONE: HassKey[dict[str, asyncio.Future[bool]]] = HassKey("setup_done")

# DATA_SETUP_STARTED is a dict [tuple[str, str | None], float], indicating when an attempt
# DATA_SETUP_STARTED is a dict, indicating when an attempt
# to setup a component started.
DATA_SETUP_STARTED = "setup_started"
DATA_SETUP_STARTED: HassKey[dict[tuple[str, str | None], float]] = HassKey(
"setup_started"
)

# DATA_SETUP_TIME is a defaultdict[str, defaultdict[str | None, defaultdict[SetupPhases, float]]]
# indicating how time was spent setting up a component and each group (config entry).
DATA_SETUP_TIME = "setup_time"
# DATA_SETUP_TIME is a defaultdict, indicating how time was spent
# setting up a component.
DATA_SETUP_TIME: HassKey[
defaultdict[str, defaultdict[str | None, defaultdict[SetupPhases, float]]]
] = HassKey("setup_time")

DATA_DEPS_REQS = "deps_reqs_processed"

Expand Down Expand Up @@ -126,9 +130,7 @@ def async_set_domains_to_be_loaded(hass: core.HomeAssistant, domains: set[str])
- Properly handle after_dependencies.
- Keep track of domains which will load but have not yet finished loading
"""
setup_done_futures: dict[str, asyncio.Future[bool]] = hass.data.setdefault(
DATA_SETUP_DONE, {}
)
setup_done_futures = hass.data.setdefault(DATA_SETUP_DONE, {})
setup_done_futures.update({domain: hass.loop.create_future() for domain in domains})


Expand All @@ -149,12 +151,8 @@ async def async_setup_component(
if domain in hass.config.components:
return True

setup_futures: dict[str, asyncio.Future[bool]] = hass.data.setdefault(
DATA_SETUP, {}
)
setup_done_futures: dict[str, asyncio.Future[bool]] = hass.data.setdefault(
DATA_SETUP_DONE, {}
)
setup_futures = hass.data.setdefault(DATA_SETUP, {})
setup_done_futures = hass.data.setdefault(DATA_SETUP_DONE, {})

if existing_setup_future := setup_futures.get(domain):
return await existing_setup_future
Expand Down Expand Up @@ -195,9 +193,7 @@ async def _async_process_dependencies(
Returns a list of dependencies which failed to set up.
"""
setup_futures: dict[str, asyncio.Future[bool]] = hass.data.setdefault(
DATA_SETUP, {}
)
setup_futures = hass.data.setdefault(DATA_SETUP, {})

dependencies_tasks = {
dep: setup_futures.get(dep)
Expand All @@ -210,7 +206,7 @@ async def _async_process_dependencies(
}

after_dependencies_tasks: dict[str, asyncio.Future[bool]] = {}
to_be_loaded: dict[str, asyncio.Future[bool]] = hass.data.get(DATA_SETUP_DONE, {})
to_be_loaded = hass.data.get(DATA_SETUP_DONE, {})
for dep in integration.after_dependencies:
if (
dep not in dependencies_tasks
Expand Down
7 changes: 0 additions & 7 deletions tests/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,6 @@ async def test_integration_only_setup_entry(hass: HomeAssistant) -> None:
async def test_async_start_setup_running(hass: HomeAssistant) -> None:
"""Test setup started context manager does nothing when running."""
assert hass.state is CoreState.running
setup_started: dict[tuple[str, str | None], float]
setup_started = hass.data.setdefault(setup.DATA_SETUP_STARTED, {})

with setup.async_start_setup(
Expand All @@ -753,7 +752,6 @@ async def test_async_start_setup_config_entry(
) -> None:
"""Test setup started keeps track of setup times with a config entry."""
hass.set_state(CoreState.not_running)
setup_started: dict[tuple[str, str | None], float]
setup_started = hass.data.setdefault(setup.DATA_SETUP_STARTED, {})
setup_time = setup._setup_times(hass)

Expand Down Expand Up @@ -864,7 +862,6 @@ async def test_async_start_setup_config_entry_late_platform(
) -> None:
"""Test setup started tracks config entry time with a late platform load."""
hass.set_state(CoreState.not_running)
setup_started: dict[tuple[str, str | None], float]
setup_started = hass.data.setdefault(setup.DATA_SETUP_STARTED, {})
setup_time = setup._setup_times(hass)

Expand Down Expand Up @@ -919,7 +916,6 @@ async def test_async_start_setup_config_entry_platform_wait(
) -> None:
"""Test setup started tracks wait time when a platform loads inside of config entry setup."""
hass.set_state(CoreState.not_running)
setup_started: dict[tuple[str, str | None], float]
setup_started = hass.data.setdefault(setup.DATA_SETUP_STARTED, {})
setup_time = setup._setup_times(hass)

Expand Down Expand Up @@ -962,7 +958,6 @@ async def test_async_start_setup_config_entry_platform_wait(
async def test_async_start_setup_top_level_yaml(hass: HomeAssistant) -> None:
"""Test setup started context manager keeps track of setup times with modern yaml."""
hass.set_state(CoreState.not_running)
setup_started: dict[tuple[str, str | None], float]
setup_started = hass.data.setdefault(setup.DATA_SETUP_STARTED, {})
setup_time = setup._setup_times(hass)

Expand All @@ -979,7 +974,6 @@ async def test_async_start_setup_top_level_yaml(hass: HomeAssistant) -> None:
async def test_async_start_setup_platform_integration(hass: HomeAssistant) -> None:
"""Test setup started keeps track of setup times a platform integration."""
hass.set_state(CoreState.not_running)
setup_started: dict[tuple[str, str | None], float]
setup_started = hass.data.setdefault(setup.DATA_SETUP_STARTED, {})
setup_time = setup._setup_times(hass)

Expand Down Expand Up @@ -1014,7 +1008,6 @@ async def test_async_start_setup_legacy_platform_integration(
) -> None:
"""Test setup started keeps track of setup times for a legacy platform integration."""
hass.set_state(CoreState.not_running)
setup_started: dict[tuple[str, str | None], float]
setup_started = hass.data.setdefault(setup.DATA_SETUP_STARTED, {})
setup_time = setup._setup_times(hass)

Expand Down

0 comments on commit 5d053ea

Please sign in to comment.