diff --git a/homeassistant/setup.py b/homeassistant/setup.py index 238f3bf3ac7..d6eb804acf0 100644 --- a/homeassistant/setup.py +++ b/homeassistant/setup.py @@ -131,17 +131,23 @@ async def async_setup_component( if domain in hass.config.components: return True - setup_tasks: dict[str, asyncio.Task[bool]] = hass.data.setdefault(DATA_SETUP, {}) - - if domain in setup_tasks: - return await setup_tasks[domain] - - task = setup_tasks[domain] = hass.async_create_task( - _async_setup_component(hass, domain, config), f"setup component {domain}" + setup_futures: dict[str, asyncio.Future[bool]] = hass.data.setdefault( + DATA_SETUP, {} ) + if existing_future := setup_futures.get(domain): + return await existing_future + + future = hass.loop.create_future() + setup_futures[domain] = future + try: - return await task + result = await _async_setup_component(hass, domain, config) + future.set_result(result) + return result + except BaseException as err: # pylint: disable=broad-except + future.set_exception(err) + raise finally: if domain in hass.data.get(DATA_SETUP_DONE, {}): hass.data[DATA_SETUP_DONE].pop(domain).set() diff --git a/tests/test_config_entries.py b/tests/test_config_entries.py index 71334b753fa..ba331102745 100644 --- a/tests/test_config_entries.py +++ b/tests/test_config_entries.py @@ -20,13 +20,7 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP, ) -from homeassistant.core import ( - DOMAIN as HA_DOMAIN, - CoreState, - Event, - HomeAssistant, - callback, -) +from homeassistant.core import DOMAIN as HA_DOMAIN, CoreState, HomeAssistant, callback from homeassistant.data_entry_flow import BaseServiceInfo, FlowResult, FlowResultType from homeassistant.exceptions import ( ConfigEntryAuthFailed, @@ -46,6 +40,7 @@ from .common import ( MockEntity, MockModule, MockPlatform, + async_capture_events, async_fire_time_changed, mock_config_flow, mock_integration, @@ -2811,14 +2806,7 @@ async def test_async_setup_init_entry_completes_before_loaded_event_fires( hass: HomeAssistant, manager: config_entries.ConfigEntries ) -> None: """Test a config entry being initialized during integration setup before the loaded event fires.""" - load_events: list[Event] = [] - - @callback - def _record_load(event: Event) -> None: - nonlocal load_events - load_events.append(event) - - listener = hass.bus.async_listen(EVENT_COMPONENT_LOADED, _record_load) + load_events = async_capture_events(hass, EVENT_COMPONENT_LOADED) async def mock_async_setup(hass, config): """Mock setup.""" @@ -2872,8 +2860,6 @@ async def test_async_setup_init_entry_completes_before_loaded_event_fires( assert len(entries) == 1 assert entries[0].state is config_entries.ConfigEntryState.LOADED - listener() - async def test_async_setup_update_entry(hass: HomeAssistant) -> None: """Test a config entry being updated during integration setup."""