diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index acb790d6915..4da10fb4608 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -100,7 +100,6 @@ async def async_setup_hass( ) -> core.HomeAssistant | None: """Set up Home Assistant.""" hass = core.HomeAssistant() - core._cv_hass.set(hass) # pylint: disable=protected-access hass.config.config_dir = runtime_config.config_dir async_enable_logging( @@ -166,6 +165,7 @@ async def async_setup_hass( old_config = hass.config old_logging = hass.data.get(DATA_LOGGING) + core._cv_hass.reset(hass._context_token) # pylint: disable=protected-access hass = core.HomeAssistant() if old_logging: hass.data[DATA_LOGGING] = old_logging diff --git a/homeassistant/core.py b/homeassistant/core.py index 98651772c13..ef8e2209bcd 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -15,7 +15,7 @@ from collections.abc import ( Iterable, Mapping, ) -from contextvars import ContextVar +from contextvars import ContextVar, Token import datetime import enum import functools @@ -178,12 +178,6 @@ def is_callback(func: Callable[..., Any]) -> bool: return getattr(func, "_hass_callback", False) is True -@callback -def async_get_hass() -> HomeAssistant: - """Return the HomeAssistant instance.""" - return _cv_hass.get() - - @enum.unique class HassJobType(enum.Enum): """Represent a job type.""" @@ -250,9 +244,23 @@ class HomeAssistant: auth: AuthManager http: HomeAssistantHTTP = None # type: ignore[assignment] config_entries: ConfigEntries = None # type: ignore[assignment] + _initialized: bool = False + _context_token: Token[HomeAssistant] + + def __new__(cls) -> HomeAssistant: + """Return the existing HA instance if it exists, otherwise create one.""" + try: + return _cv_hass.get() + except LookupError: + hass = super().__new__(cls) + hass._context_token = _cv_hass.set(hass) + return hass def __init__(self) -> None: """Initialize new Home Assistant object.""" + if self._initialized: + return + self._initialized = True self.loop = asyncio.get_running_loop() self._pending_tasks: list[asyncio.Future[Any]] = [] self._track_task = True diff --git a/tests/test_bootstrap.py b/tests/test_bootstrap.py index 56c15f49337..91beb44be25 100644 --- a/tests/test_bootstrap.py +++ b/tests/test_bootstrap.py @@ -501,7 +501,7 @@ async def test_setup_hass( assert len(mock_ensure_config_exists.mock_calls) == 1 assert len(mock_process_ha_config_upgrade.mock_calls) == 1 - assert hass == core.async_get_hass() + assert hass == core.HomeAssistant() async def test_setup_hass_takes_longer_than_log_slow_startup(