mirror of
https://github.com/home-assistant/core.git
synced 2025-04-19 14:57:52 +00:00
Use common helper function in resolve integration dependencies (#140989)
Extract to helper function in resolve integration dependencies
This commit is contained in:
parent
eee6e8a2c3
commit
efbb94a1b1
@ -1447,31 +1447,13 @@ async def resolve_integrations_dependencies(
|
||||
|
||||
Detects circular dependencies and missing integrations.
|
||||
"""
|
||||
resolved = _ResolveDependenciesCache()
|
||||
|
||||
async def _resolve_deps_catch_exceptions(itg: Integration) -> set[str] | None:
|
||||
try:
|
||||
return await _do_resolve_dependencies(itg, cache=resolved)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
_LOGGER.error("Unable to resolve dependencies for %s: %s", itg.domain, exc)
|
||||
return None
|
||||
|
||||
resolve_dependencies_tasks = {
|
||||
itg.domain: create_eager_task(
|
||||
_resolve_deps_catch_exceptions(itg),
|
||||
name=f"resolve dependencies {itg.domain}",
|
||||
loop=hass.loop,
|
||||
)
|
||||
for itg in integrations
|
||||
}
|
||||
|
||||
result = await asyncio.gather(*resolve_dependencies_tasks.values())
|
||||
|
||||
return {
|
||||
domain: deps
|
||||
for domain, deps in zip(resolve_dependencies_tasks, result, strict=True)
|
||||
if deps is not None
|
||||
}
|
||||
return await _resolve_integrations_dependencies(
|
||||
hass,
|
||||
"resolve dependencies",
|
||||
integrations,
|
||||
cache=_ResolveDependenciesCache(),
|
||||
ignore_exceptions=False,
|
||||
)
|
||||
|
||||
|
||||
async def resolve_integrations_after_dependencies(
|
||||
@ -1485,26 +1467,46 @@ async def resolve_integrations_after_dependencies(
|
||||
|
||||
Detects circular dependencies and missing integrations.
|
||||
"""
|
||||
resolved: dict[Integration, set[str] | Exception] = {}
|
||||
return await _resolve_integrations_dependencies(
|
||||
hass,
|
||||
"resolve (after) dependencies",
|
||||
integrations,
|
||||
cache={},
|
||||
possible_after_dependencies=possible_after_dependencies,
|
||||
ignore_exceptions=ignore_exceptions,
|
||||
)
|
||||
|
||||
|
||||
async def _resolve_integrations_dependencies(
|
||||
hass: HomeAssistant,
|
||||
name: str,
|
||||
integrations: Iterable[Integration],
|
||||
*,
|
||||
cache: _ResolveDependenciesCacheProtocol,
|
||||
possible_after_dependencies: set[str] | None | UndefinedType = UNDEFINED,
|
||||
ignore_exceptions: bool,
|
||||
) -> dict[str, set[str]]:
|
||||
"""Resolve all dependencies, possibly including after_dependencies, for integrations.
|
||||
|
||||
Detects circular dependencies and missing integrations.
|
||||
"""
|
||||
|
||||
async def _resolve_deps_catch_exceptions(itg: Integration) -> set[str] | None:
|
||||
try:
|
||||
return await _do_resolve_dependencies(
|
||||
return await _resolve_integration_dependencies(
|
||||
itg,
|
||||
cache=resolved,
|
||||
cache=cache,
|
||||
possible_after_dependencies=possible_after_dependencies,
|
||||
ignore_exceptions=ignore_exceptions,
|
||||
)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
_LOGGER.error(
|
||||
"Unable to resolve (after) dependencies for %s: %s", itg.domain, exc
|
||||
)
|
||||
_LOGGER.error("Unable to %s for %s: %s", name, itg.domain, exc)
|
||||
return None
|
||||
|
||||
resolve_dependencies_tasks = {
|
||||
itg.domain: create_eager_task(
|
||||
_resolve_deps_catch_exceptions(itg),
|
||||
name=f"resolve after dependencies {itg.domain}",
|
||||
name=f"{name} {itg.domain}",
|
||||
loop=hass.loop,
|
||||
)
|
||||
for itg in integrations
|
||||
@ -1519,7 +1521,7 @@ async def resolve_integrations_after_dependencies(
|
||||
}
|
||||
|
||||
|
||||
async def _do_resolve_dependencies(
|
||||
async def _resolve_integration_dependencies(
|
||||
itg: Integration,
|
||||
*,
|
||||
cache: _ResolveDependenciesCacheProtocol,
|
||||
@ -1542,7 +1544,7 @@ async def _do_resolve_dependencies(
|
||||
resolved = cache
|
||||
resolving: set[str] = set()
|
||||
|
||||
async def do_resolve_dependencies_impl(itg: Integration) -> set[str]:
|
||||
async def resolve_dependencies_impl(itg: Integration) -> set[str]:
|
||||
domain = itg.domain
|
||||
|
||||
# If it's already resolved, no point doing it again.
|
||||
@ -1584,7 +1586,7 @@ async def _do_resolve_dependencies(
|
||||
all_dependencies.add(dep_domain)
|
||||
|
||||
try:
|
||||
dep_dependencies = await do_resolve_dependencies_impl(dep_integration)
|
||||
dep_dependencies = await resolve_dependencies_impl(dep_integration)
|
||||
except CircularDependency as exc:
|
||||
exc.extend_cycle(domain)
|
||||
resolved[itg] = exc
|
||||
@ -1600,7 +1602,7 @@ async def _do_resolve_dependencies(
|
||||
resolved[itg] = all_dependencies
|
||||
return all_dependencies
|
||||
|
||||
return await do_resolve_dependencies_impl(itg)
|
||||
return await resolve_dependencies_impl(itg)
|
||||
|
||||
|
||||
class LoaderError(Exception):
|
||||
|
@ -29,25 +29,25 @@ async def test_circular_component_dependencies(hass: HomeAssistant) -> None:
|
||||
mod_4 = mock_integration(hass, MockModule("mod4", dependencies=["mod2", "mod3"]))
|
||||
all_domains = {"mod1", "mod2", "mod3", "mod4"}
|
||||
|
||||
deps = await loader._do_resolve_dependencies(mod_4, cache={})
|
||||
deps = await loader._resolve_integration_dependencies(mod_4, cache={})
|
||||
assert deps == {"mod1", "mod2", "mod3"}
|
||||
|
||||
# Create a circular dependency
|
||||
mock_integration(hass, MockModule("mod1", dependencies=["mod4"]))
|
||||
with pytest.raises(loader.CircularDependency):
|
||||
await loader._do_resolve_dependencies(mod_4, cache={})
|
||||
await loader._resolve_integration_dependencies(mod_4, cache={})
|
||||
|
||||
# Create a different circular dependency
|
||||
mock_integration(hass, MockModule("mod1", dependencies=["mod3"]))
|
||||
with pytest.raises(loader.CircularDependency):
|
||||
await loader._do_resolve_dependencies(mod_4, cache={})
|
||||
await loader._resolve_integration_dependencies(mod_4, cache={})
|
||||
|
||||
# Create a circular after_dependency
|
||||
mock_integration(
|
||||
hass, MockModule("mod1", partial_manifest={"after_dependencies": ["mod4"]})
|
||||
)
|
||||
with pytest.raises(loader.CircularDependency):
|
||||
await loader._do_resolve_dependencies(
|
||||
await loader._resolve_integration_dependencies(
|
||||
mod_4,
|
||||
cache={},
|
||||
possible_after_dependencies=all_domains,
|
||||
@ -58,7 +58,7 @@ async def test_circular_component_dependencies(hass: HomeAssistant) -> None:
|
||||
hass, MockModule("mod1", partial_manifest={"after_dependencies": ["mod3"]})
|
||||
)
|
||||
with pytest.raises(loader.CircularDependency):
|
||||
await loader._do_resolve_dependencies(
|
||||
await loader._resolve_integration_dependencies(
|
||||
mod_4,
|
||||
cache={},
|
||||
possible_after_dependencies=all_domains,
|
||||
@ -72,7 +72,7 @@ async def test_circular_component_dependencies(hass: HomeAssistant) -> None:
|
||||
hass, MockModule("mod4", partial_manifest={"after_dependencies": ["mod2"]})
|
||||
)
|
||||
with pytest.raises(loader.CircularDependency):
|
||||
await loader._do_resolve_dependencies(
|
||||
await loader._resolve_integration_dependencies(
|
||||
mod_4,
|
||||
cache={},
|
||||
possible_after_dependencies=all_domains,
|
||||
|
Loading…
x
Reference in New Issue
Block a user