Avoid pre-importing config_flows if the integration does not support migration (#113369)

* Avoid pre-importing config_flows if the integration does support migration

Currently we pre-import the config flow module if it exists since
setting up the config entry required comparing the versions found
in the config_flow.py. We can avoid the pre-import if the integration
does not support async_migrate_entry which means we avoid loading
many config flows in memory at startup.

* cover

* fix missing block

* do not call directly

* its too fast now, the test gets more along

* Update homeassistant/loader.py
This commit is contained in:
J. Nick Koston 2024-03-13 18:13:40 -10:00 committed by GitHub
parent d1d28dbfb8
commit 9940f51b95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 89 additions and 42 deletions

View file

@ -1204,31 +1204,21 @@ async def test_async_get_component_loads_loop_if_already_in_sys_modules(
assert "test_package_loaded_executor" not in hass.config.components
assert "test_package_loaded_executor.config_flow" not in hass.config.components
config_flow_module_name = f"{integration.pkg_path}.config_flow"
module_mock = MagicMock(__file__="__init__.py")
config_flow_module_mock = MagicMock(__file__="config_flow.py")
module_mock = object()
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},
{**sys.modules, 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 "loaded_executor=False" in caplog.text
assert module is module_mock
caplog.clear()
@ -1236,7 +1226,6 @@ async def test_async_get_component_loads_loop_if_already_in_sys_modules(
"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()
@ -1246,6 +1235,10 @@ async def test_async_get_component_loads_loop_if_already_in_sys_modules(
assert "loaded_executor" not in caplog.text
assert module is module_mock
# The integration does not implement async_migrate_entry so it
# should not be preloaded
assert integration.get_platform_cached("config_flow") is None
async def test_async_get_component_concurrent_loads(
hass: HomeAssistant,