Reduce overhead to start a config entry flow by optimizing fetching the handler (#97883)

This commit is contained in:
J. Nick Koston 2023-08-06 20:25:03 -10:00 committed by GitHub
parent 369a484a78
commit 1adfa6bbeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 12 deletions

View File

@ -964,10 +964,9 @@ class ConfigEntriesFlowManager(data_entry_flow.FlowManager):
Handler key is the domain of the component that we want to set up. Handler key is the domain of the component that we want to set up.
""" """
await _load_integration(self.hass, handler_key, self._hass_config) handler = await _async_get_flow_handler(
if (handler := HANDLERS.get(handler_key)) is None: self.hass, handler_key, self._hass_config
raise data_entry_flow.UnknownHandler )
if not context or "source" not in context: if not context or "source" not in context:
raise KeyError("Context not set or doesn't have a source set") raise KeyError("Context not set or doesn't have a source set")
@ -1830,12 +1829,8 @@ class OptionsFlowManager(data_entry_flow.FlowManager):
if entry is None: if entry is None:
raise UnknownEntry(handler_key) raise UnknownEntry(handler_key)
await _load_integration(self.hass, entry.domain, {}) handler = await _async_get_flow_handler(self.hass, entry.domain, {})
return handler.async_get_options_flow(entry)
if entry.domain not in HANDLERS:
raise data_entry_flow.UnknownHandler
return HANDLERS[entry.domain].async_get_options_flow(entry)
async def async_finish_flow( async def async_finish_flow(
self, flow: data_entry_flow.FlowHandler, result: data_entry_flow.FlowResult self, flow: data_entry_flow.FlowHandler, result: data_entry_flow.FlowResult
@ -2021,9 +2016,15 @@ async def support_remove_from_device(hass: HomeAssistant, domain: str) -> bool:
return hasattr(component, "async_remove_config_entry_device") return hasattr(component, "async_remove_config_entry_device")
async def _load_integration( async def _async_get_flow_handler(
hass: HomeAssistant, domain: str, hass_config: ConfigType hass: HomeAssistant, domain: str, hass_config: ConfigType
) -> None: ) -> type[ConfigFlow]:
"""Get a flow handler for specified domain."""
# First check if there is a handler registered for the domain
if domain in hass.config.components and (handler := HANDLERS.get(domain)):
return handler
try: try:
integration = await loader.async_get_integration(hass, domain) integration = await loader.async_get_integration(hass, domain)
except loader.IntegrationNotFound as err: except loader.IntegrationNotFound as err:
@ -2042,3 +2043,8 @@ async def _load_integration(
err, err,
) )
raise data_entry_flow.UnknownHandler raise data_entry_flow.UnknownHandler
if handler := HANDLERS.get(domain):
return handler
raise data_entry_flow.UnknownHandler

View File

@ -1544,6 +1544,28 @@ async def test_init_custom_integration(hass: HomeAssistant) -> None:
await hass.config_entries.flow.async_init("bla", context={"source": "user"}) await hass.config_entries.flow.async_init("bla", context={"source": "user"})
async def test_init_custom_integration_with_missing_handler(
hass: HomeAssistant,
) -> None:
"""Test initializing flow for custom integration with a missing handler."""
integration = loader.Integration(
hass,
"custom_components.hue",
None,
{"name": "Hue", "dependencies": [], "requirements": [], "domain": "hue"},
)
mock_integration(
hass,
MockModule("hue"),
)
mock_entity_platform(hass, "config_flow.hue", None)
with pytest.raises(data_entry_flow.UnknownHandler), patch(
"homeassistant.loader.async_get_integration",
return_value=integration,
):
await hass.config_entries.flow.async_init("bla", context={"source": "user"})
async def test_support_entry_unload(hass: HomeAssistant) -> None: async def test_support_entry_unload(hass: HomeAssistant) -> None:
"""Test unloading entry.""" """Test unloading entry."""
assert await config_entries.support_entry_unload(hass, "light") assert await config_entries.support_entry_unload(hass, "light")