diff --git a/homeassistant/components/stt/__init__.py b/homeassistant/components/stt/__init__.py index caa094f88e..cb1c646ef7 100644 --- a/homeassistant/components/stt/__init__.py +++ b/homeassistant/components/stt/__init__.py @@ -17,7 +17,7 @@ from aiohttp.web_exceptions import ( from homeassistant.components.http import HomeAssistantView from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers import engine, engine_component +from homeassistant.helpers import engine_component from homeassistant.helpers.typing import ConfigType from .const import ( @@ -95,7 +95,7 @@ class SpeechResult: result: SpeechResultState -class Provider(engine.Engine, ABC): +class Provider(engine_component.Engine, ABC): """Represent a single STT provider.""" hass: HomeAssistant | None = None diff --git a/homeassistant/helpers/engine.py b/homeassistant/helpers/engine.py deleted file mode 100644 index 99a7e9661a..0000000000 --- a/homeassistant/helpers/engine.py +++ /dev/null @@ -1,26 +0,0 @@ -"""Base class for Home Assistant engines.""" - - -class Engine: - """Base class for Home Assistant engines.""" - - async def async_internal_added_to_hass(self) -> None: - """Run when service about to be added to hass. - - Not to be extended by integrations. - """ - - async def async_added_to_hass(self) -> None: - """Run when service about to be added to hass. - - Not to be extended by integrations. - """ - - async def async_internal_will_remove_from_hass(self) -> None: - """Prepare to remove the service from Home Assistant. - - Not to be extended by integrations. - """ - - async def async_will_remove_from_hass(self) -> None: - """Prepare to remove the service from Home Assistant.""" diff --git a/homeassistant/helpers/engine_component.py b/homeassistant/helpers/engine_component.py index 75873a9237..b925f5da02 100644 --- a/homeassistant/helpers/engine_component.py +++ b/homeassistant/helpers/engine_component.py @@ -2,20 +2,55 @@ from __future__ import annotations import logging -from typing import Generic, TypeVar +from typing import Generic, Protocol, TypeVar, cast from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.setup import async_prepare_setup_platform -from .engine import Engine -from .engine_platform import EnginePlatform from .typing import ConfigType -_EngineT = TypeVar("_EngineT", bound=Engine) + +class Engine: + """Base class for Home Assistant engines.""" + + async def async_internal_added_to_hass(self) -> None: + """Run when service about to be added to hass. + + Not to be extended by integrations. + """ + + async def async_added_to_hass(self) -> None: + """Run when service about to be added to hass. + + Not to be extended by integrations. + """ + + async def async_internal_will_remove_from_hass(self) -> None: + """Prepare to remove the service from Home Assistant. + + Not to be extended by integrations. + """ + + async def async_will_remove_from_hass(self) -> None: + """Prepare to remove the service from Home Assistant.""" -class EngineComponent(Generic[_EngineT]): +_EngineT_co = TypeVar("_EngineT_co", bound=Engine, covariant=True) + + +class EnginePlatformModule(Protocol[_EngineT_co]): + """Protocol type for engine platform modules.""" + + async def async_setup_entry( + self, + hass: HomeAssistant, + entry: ConfigEntry, + ) -> _EngineT_co: + """Set up an integration platform from a config entry.""" + + +class EngineComponent(Generic[_EngineT_co]): """Track engines for a component.""" def __init__( @@ -30,22 +65,17 @@ class EngineComponent(Generic[_EngineT]): self.domain = domain self.hass = hass self.config = config - self._platforms: dict[str, EnginePlatform[_EngineT]] = {} + self._engines: dict[str, _EngineT_co] = {} @callback - def async_get_engine(self, config_entry_id: str) -> _EngineT | None: + def async_get_engine(self, config_entry_id: str) -> _EngineT_co | None: """Return a wrapped engine.""" - platform = self._platforms.get(config_entry_id) - return None if platform is None else platform.engine + return self._engines.get(config_entry_id) @callback - def async_get_engines(self) -> list[_EngineT]: + def async_get_engines(self) -> list[_EngineT_co]: """Return a wrapped engine.""" - return [ - platform.engine - for platform in self._platforms.values() - if platform.engine is not None - ] + return list(self._engines.values()) async def async_setup_entry(self, config_entry: ConfigEntry) -> bool: """Set up a config entry.""" @@ -64,23 +94,34 @@ class EngineComponent(Generic[_EngineT]): key = config_entry.entry_id - if key in self._platforms: + if key in self._engines: raise ValueError("Config entry has already been setup!") - self._platforms[key] = EnginePlatform( - self.logger, - self.hass, - config_entry, - platform, - ) + try: + engine = await cast( + EnginePlatformModule[_EngineT_co], platform + ).async_setup_entry(self.hass, config_entry) + await engine.async_internal_added_to_hass() + await engine.async_added_to_hass() + except Exception: # pylint: disable=broad-except + self.logger.exception("Error setting up entry %s", config_entry.entry_id) + return False - return await self._platforms[key].async_setup_entry() + self._engines[key] = engine + return True async def async_unload_entry(self, config_entry: ConfigEntry) -> bool: """Unload a config entry.""" key = config_entry.entry_id - if (platform := self._platforms.pop(key, None)) is None: + if (engine := self._engines.pop(key, None)) is None: raise ValueError("Config entry was never loaded!") - return await platform.async_unload_entry() + try: + await engine.async_internal_will_remove_from_hass() + await engine.async_will_remove_from_hass() + except Exception: # pylint: disable=broad-except + self.logger.exception("Error unloading entry %s", config_entry.entry_id) + return False + + return True diff --git a/homeassistant/helpers/engine_platform.py b/homeassistant/helpers/engine_platform.py deleted file mode 100644 index 95397213dd..0000000000 --- a/homeassistant/helpers/engine_platform.py +++ /dev/null @@ -1,65 +0,0 @@ -"""Service platform helper.""" -import logging -from typing import Generic, Protocol, TypeVar - -from homeassistant.config_entries import ConfigEntry -from homeassistant.core import HomeAssistant - -from .engine import Engine - -_EngineT_co = TypeVar("_EngineT_co", bound=Engine, covariant=True) - - -class EnginePlatformModule(Protocol[_EngineT_co]): - """Protocol type for engine platform modules.""" - - async def async_setup_entry( - self, - hass: HomeAssistant, - entry: ConfigEntry, - ) -> _EngineT_co: - """Set up an integration platform from a config entry.""" - - -class EnginePlatform(Generic[_EngineT_co]): - """Track engines for a platform.""" - - def __init__( - self, - logger: logging.Logger, - hass: HomeAssistant, - config_entry: ConfigEntry, - platform: EnginePlatformModule, - ) -> None: - """Initialize the engine platform.""" - self.logger = logger - self.hass = hass - self.config_entry = config_entry - self.platform = platform - self.engine: _EngineT_co | None = None - - async def async_setup_entry(self) -> bool: - """Set up a config entry.""" - try: - engine = await self.platform.async_setup_entry(self.hass, self.config_entry) - except Exception: # pylint: disable=broad-except - self.logger.exception( - "Error setting up entry %s", self.config_entry.entry_id - ) - return False - - await engine.async_internal_added_to_hass() - await engine.async_added_to_hass() - - self.engine = engine - return True - - async def async_unload_entry(self) -> bool: - """Unload a config entry.""" - if self.engine is None: - return True - - await self.engine.async_internal_will_remove_from_hass() - await self.engine.async_will_remove_from_hass() - self.engine = None - return True