From e9a78700802857fc7bc38e53c68637e1ba270ce0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 21 Jan 2024 18:09:33 -1000 Subject: [PATCH] Small cleanups to async_get_all_descriptions (#108633) --- homeassistant/helpers/service.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/homeassistant/helpers/service.py b/homeassistant/helpers/service.py index 781d41a08d7..f00e80f43d8 100644 --- a/homeassistant/helpers/service.py +++ b/homeassistant/helpers/service.py @@ -581,31 +581,36 @@ async def async_get_all_descriptions( descriptions_cache: dict[ tuple[str, str], dict[str, Any] | None ] = hass.data.setdefault(SERVICE_DESCRIPTION_CACHE, {}) - services = hass.services.async_services() + + # We don't mutate services here so we avoid calling + # async_services which makes a copy of every services + # dict. + services = hass.services._services # pylint: disable=protected-access # See if there are new services not seen before. # Any service that we saw before already has an entry in description_cache. - missing = set() - all_services = [] - for domain in services: - for service_name in services[domain]: + domains_with_missing_services: set[str] = set() + all_services: set[tuple[str, str]] = set() + for domain, services_by_domain in services.items(): + for service_name in services_by_domain: cache_key = (domain, service_name) - all_services.append(cache_key) + all_services.add(cache_key) if cache_key not in descriptions_cache: - missing.add(domain) + domains_with_missing_services.add(domain) # If we have a complete cache, check if it is still valid + all_cache: tuple[set[tuple[str, str]], dict[str, dict[str, Any]]] | None if all_cache := hass.data.get(ALL_SERVICE_DESCRIPTIONS_CACHE): previous_all_services, previous_descriptions_cache = all_cache # If the services are the same, we can return the cache if previous_all_services == all_services: - return cast(dict[str, dict[str, Any]], previous_descriptions_cache) + return previous_descriptions_cache # type: ignore[no-any-return] # Files we loaded for missing descriptions loaded: dict[str, JSON_TYPE] = {} - if missing: - ints_or_excs = await async_get_integrations(hass, missing) + if domains_with_missing_services: + ints_or_excs = await async_get_integrations(hass, domains_with_missing_services) integrations: list[Integration] = [] for domain, int_or_exc in ints_or_excs.items(): if type(int_or_exc) is Integration: # noqa: E721 @@ -617,11 +622,11 @@ async def async_get_all_descriptions( contents = await hass.async_add_executor_job( _load_services_files, hass, integrations ) - loaded = dict(zip(missing, contents)) + loaded = dict(zip(domains_with_missing_services, contents)) # Load translations for all service domains translations = await translation.async_get_translations( - hass, "en", "services", list(services) + hass, "en", "services", services ) # Build response