mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Fix async_get_component loading in the executor when the module is already loaded (#112153)
This commit is contained in:
parent
bef8376f83
commit
f4b2c9b569
@ -847,8 +847,9 @@ class Integration:
|
||||
domain = self.domain
|
||||
# Some integrations fail on import because they call functions incorrectly.
|
||||
# So we do it before validating config to catch these errors.
|
||||
load_executor = (
|
||||
self.import_executor and f"{self.pkg_path}.{domain}" not in sys.modules
|
||||
load_executor = self.import_executor and (
|
||||
self.pkg_path not in sys.modules
|
||||
or (self.config_flow and f"{self.pkg_path}.config_flow" not in sys.modules)
|
||||
)
|
||||
if load_executor:
|
||||
try:
|
||||
|
@ -1073,6 +1073,66 @@ async def test_async_get_component_preloads_config_and_config_flow(
|
||||
)
|
||||
|
||||
|
||||
async def test_async_get_component_loads_loop_if_already_in_sys_modules(
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
enable_custom_integrations: None,
|
||||
) -> None:
|
||||
"""Verify async_get_component does not create an executor job if the module is already in sys.modules."""
|
||||
integration = await loader.async_get_integration(
|
||||
hass, "test_package_loaded_executor"
|
||||
)
|
||||
assert integration.pkg_path == "custom_components.test_package_loaded_executor"
|
||||
assert integration.import_executor is True
|
||||
assert integration.config_flow is True
|
||||
|
||||
assert "executor_import" not in hass.config.components
|
||||
assert "executor_import.config_flow" not in hass.config.components
|
||||
|
||||
config_flow_module_name = f"{integration.pkg_path}.config_flow"
|
||||
module_mock = MagicMock()
|
||||
config_flow_module_mock = MagicMock()
|
||||
|
||||
def import_module(name: str) -> Any:
|
||||
if name == integration.pkg_path:
|
||||
return module_mock
|
||||
if name == config_flow_module_name:
|
||||
return config_flow_module_mock
|
||||
raise ImportError
|
||||
|
||||
modules_without_config_flow = {
|
||||
k: v for k, v in sys.modules.items() if k != config_flow_module_name
|
||||
}
|
||||
with patch.dict(
|
||||
"sys.modules",
|
||||
{**modules_without_config_flow, integration.pkg_path: module_mock},
|
||||
clear=True,
|
||||
), patch("homeassistant.loader.importlib.import_module", import_module):
|
||||
module = await integration.async_get_component()
|
||||
|
||||
# The config flow is missing so we should load
|
||||
# in the executor
|
||||
assert "loaded_executor=True" in caplog.text
|
||||
assert "loaded_executor=False" not in caplog.text
|
||||
assert module is module_mock
|
||||
caplog.clear()
|
||||
|
||||
with patch.dict(
|
||||
"sys.modules",
|
||||
{
|
||||
integration.pkg_path: module_mock,
|
||||
config_flow_module_name: config_flow_module_mock,
|
||||
},
|
||||
), patch("homeassistant.loader.importlib.import_module", import_module):
|
||||
module = await integration.async_get_component()
|
||||
|
||||
# Everything is there so we should load in the event loop
|
||||
# since it will all be cached
|
||||
assert "loaded_executor=False" in caplog.text
|
||||
assert "loaded_executor=True" not in caplog.text
|
||||
assert module is module_mock
|
||||
|
||||
|
||||
async def test_async_get_component_deadlock_fallback(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user