mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Add loader.async_get_loaded_integration (#99440)
* Add loader.async_get_loaded_integration * Decorate async_get_loaded_integration with @callback
This commit is contained in:
parent
7c595ee2da
commit
7643820e59
@ -32,7 +32,7 @@ from urllib.parse import urlparse
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
import yarl
|
import yarl
|
||||||
|
|
||||||
from . import block_async_io, loader, util
|
from . import block_async_io, util
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_DOMAIN,
|
ATTR_DOMAIN,
|
||||||
ATTR_FRIENDLY_NAME,
|
ATTR_FRIENDLY_NAME,
|
||||||
@ -310,6 +310,9 @@ class HomeAssistant:
|
|||||||
|
|
||||||
def __init__(self, config_dir: str) -> None:
|
def __init__(self, config_dir: str) -> None:
|
||||||
"""Initialize new Home Assistant object."""
|
"""Initialize new Home Assistant object."""
|
||||||
|
# pylint: disable-next=import-outside-toplevel
|
||||||
|
from . import loader
|
||||||
|
|
||||||
self.loop = asyncio.get_running_loop()
|
self.loop = asyncio.get_running_loop()
|
||||||
self._tasks: set[asyncio.Future[Any]] = set()
|
self._tasks: set[asyncio.Future[Any]] = set()
|
||||||
self._background_tasks: set[asyncio.Future[Any]] = set()
|
self._background_tasks: set[asyncio.Future[Any]] = set()
|
||||||
|
@ -25,6 +25,7 @@ from awesomeversion import (
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from . import generated
|
from . import generated
|
||||||
|
from .core import HomeAssistant, callback
|
||||||
from .generated.application_credentials import APPLICATION_CREDENTIALS
|
from .generated.application_credentials import APPLICATION_CREDENTIALS
|
||||||
from .generated.bluetooth import BLUETOOTH
|
from .generated.bluetooth import BLUETOOTH
|
||||||
from .generated.dhcp import DHCP
|
from .generated.dhcp import DHCP
|
||||||
@ -37,7 +38,6 @@ from .util.json import JSON_DECODE_EXCEPTIONS, json_loads
|
|||||||
# Typing imports that create a circular dependency
|
# Typing imports that create a circular dependency
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .config_entries import ConfigEntry
|
from .config_entries import ConfigEntry
|
||||||
from .core import HomeAssistant
|
|
||||||
from .helpers import device_registry as dr
|
from .helpers import device_registry as dr
|
||||||
from .helpers.typing import ConfigType
|
from .helpers.typing import ConfigType
|
||||||
|
|
||||||
@ -875,6 +875,22 @@ def _resolve_integrations_from_root(
|
|||||||
return integrations
|
return integrations
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_get_loaded_integration(hass: HomeAssistant, domain: str) -> Integration:
|
||||||
|
"""Get an integration which is already loaded.
|
||||||
|
|
||||||
|
Raises IntegrationNotLoaded if the integration is not loaded.
|
||||||
|
"""
|
||||||
|
cache = hass.data[DATA_INTEGRATIONS]
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
cache = cast(dict[str, Integration | asyncio.Future[None]], cache)
|
||||||
|
int_or_fut = cache.get(domain, _UNDEF)
|
||||||
|
# Integration is never subclassed, so we can check for type
|
||||||
|
if type(int_or_fut) is Integration: # noqa: E721
|
||||||
|
return int_or_fut
|
||||||
|
raise IntegrationNotLoaded(domain)
|
||||||
|
|
||||||
|
|
||||||
async def async_get_integration(hass: HomeAssistant, domain: str) -> Integration:
|
async def async_get_integration(hass: HomeAssistant, domain: str) -> Integration:
|
||||||
"""Get integration."""
|
"""Get integration."""
|
||||||
integrations_or_excs = await async_get_integrations(hass, [domain])
|
integrations_or_excs = await async_get_integrations(hass, [domain])
|
||||||
@ -970,6 +986,15 @@ class IntegrationNotFound(LoaderError):
|
|||||||
self.domain = domain
|
self.domain = domain
|
||||||
|
|
||||||
|
|
||||||
|
class IntegrationNotLoaded(LoaderError):
|
||||||
|
"""Raised when a component is not loaded."""
|
||||||
|
|
||||||
|
def __init__(self, domain: str) -> None:
|
||||||
|
"""Initialize a component not found error."""
|
||||||
|
super().__init__(f"Integration '{domain}' not loaded.")
|
||||||
|
self.domain = domain
|
||||||
|
|
||||||
|
|
||||||
class CircularDependency(LoaderError):
|
class CircularDependency(LoaderError):
|
||||||
"""Raised when a circular dependency is found when resolving components."""
|
"""Raised when a circular dependency is found when resolving components."""
|
||||||
|
|
||||||
|
@ -150,10 +150,17 @@ async def test_custom_integration_version_not_valid(
|
|||||||
|
|
||||||
async def test_get_integration(hass: HomeAssistant) -> None:
|
async def test_get_integration(hass: HomeAssistant) -> None:
|
||||||
"""Test resolving integration."""
|
"""Test resolving integration."""
|
||||||
|
with pytest.raises(loader.IntegrationNotLoaded):
|
||||||
|
loader.async_get_loaded_integration(hass, "hue")
|
||||||
|
|
||||||
integration = await loader.async_get_integration(hass, "hue")
|
integration = await loader.async_get_integration(hass, "hue")
|
||||||
assert hue == integration.get_component()
|
assert hue == integration.get_component()
|
||||||
assert hue_light == integration.get_platform("light")
|
assert hue_light == integration.get_platform("light")
|
||||||
|
|
||||||
|
integration = loader.async_get_loaded_integration(hass, "hue")
|
||||||
|
assert hue == integration.get_component()
|
||||||
|
assert hue_light == integration.get_platform("light")
|
||||||
|
|
||||||
|
|
||||||
async def test_get_integration_exceptions(hass: HomeAssistant) -> None:
|
async def test_get_integration_exceptions(hass: HomeAssistant) -> None:
|
||||||
"""Test resolving integration."""
|
"""Test resolving integration."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user