Try to preload the config platform when loading a component (#112104)

This commit is contained in:
J. Nick Koston 2024-03-03 10:23:08 -10:00 committed by GitHub
parent 372886bf6c
commit ba9733e90b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 0 deletions

View File

@ -1458,6 +1458,9 @@ async def async_process_component_config( # noqa: C901
# Check if the integration has a custom config validator
config_validator = None
# A successful call to async_get_component will prime
# the cache for platform_exists to ensure it does no
# blocking I/O
if integration.platform_exists("config") is not False:
# If the config platform cannot possibly exist, don't try to load it.
try:

View File

@ -900,6 +900,14 @@ class Integration:
)
raise ImportError(f"Exception importing {self.pkg_path}") from err
if self.platform_exists("config"):
# Setting up a component always checks if the config
# platform exists. Since we may be running in the executor
# we will use this opportunity to cache the config platform
# as well.
with suppress(ImportError):
self.get_platform("config")
return cache[self.domain]
async def async_get_platform(self, platform_name: str) -> ModuleType:

View File

@ -1038,6 +1038,37 @@ async def test_hass_components_use_reported(
) in caplog.text
async def test_async_get_component_preloads_config(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Verify async_get_component will try to preload the config platform."""
executor_import_integration = _get_test_integration(
hass, "executor_import", True, import_executor=True
)
assert executor_import_integration.import_executor is True
assert "homeassistant.components.executor_import" not in sys.modules
assert "custom_components.executor_import" not in sys.modules
with patch(
"homeassistant.loader.importlib.import_module"
) as mock_import, patch.object(
executor_import_integration, "platform_exists", return_value=True
) as mock_platform_exists:
await executor_import_integration.async_get_component()
assert mock_platform_exists.call_count == 1
assert mock_import.call_count == 2
assert (
mock_import.call_args_list[0][0][0]
== "homeassistant.components.executor_import"
)
assert (
mock_import.call_args_list[1][0][0]
== "homeassistant.components.executor_import.config"
)
async def test_async_get_component_deadlock_fallback(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None: