Convert referenced registry functions to use cached_property (#108895)

* Convert referenced registry functions to use cached_property

These already implemented caching, but now that we can use cached_property
because the lock problem is solved, we can make the code simplier and faster

* missed one

* make them the same
pull/108937/head
J. Nick Koston 2024-01-26 18:02:42 -10:00 committed by GitHub
parent 0120d00081
commit f96f4d31f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 55 deletions

View File

@ -7,7 +7,7 @@ from collections.abc import Callable, Mapping
from dataclasses import dataclass
from functools import partial
import logging
from typing import Any, Protocol, cast
from typing import TYPE_CHECKING, Any, Protocol, cast
import voluptuous as vol
@ -111,6 +111,12 @@ from .const import (
from .helpers import async_get_blueprints
from .trace import trace_automation
if TYPE_CHECKING:
from functools import cached_property
else:
from homeassistant.backports.functools import cached_property
ENTITY_ID_FORMAT = DOMAIN + ".{}"
@ -334,7 +340,7 @@ class BaseAutomationEntity(ToggleEntity, ABC):
return {CONF_ID: self.unique_id}
return None
@property
@cached_property
@abstractmethod
def referenced_areas(self) -> set[str]:
"""Return a set of referenced areas."""
@ -344,12 +350,12 @@ class BaseAutomationEntity(ToggleEntity, ABC):
def referenced_blueprint(self) -> str | None:
"""Return referenced blueprint or None."""
@property
@cached_property
@abstractmethod
def referenced_devices(self) -> set[str]:
"""Return a set of referenced devices."""
@property
@cached_property
@abstractmethod
def referenced_entities(self) -> set[str]:
"""Return a set of referenced entities."""
@ -389,7 +395,7 @@ class UnavailableAutomationEntity(BaseAutomationEntity):
"""Return the name of the entity."""
return self._name
@property
@cached_property
def referenced_areas(self) -> set[str]:
"""Return a set of referenced areas."""
return set()
@ -399,12 +405,12 @@ class UnavailableAutomationEntity(BaseAutomationEntity):
"""Return referenced blueprint or None."""
return None
@property
@cached_property
def referenced_devices(self) -> set[str]:
"""Return a set of referenced devices."""
return set()
@property
@cached_property
def referenced_entities(self) -> set[str]:
"""Return a set of referenced entities."""
return set()
@ -446,8 +452,6 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
self.action_script.change_listener = self.async_write_ha_state
self._initial_state = initial_state
self._is_enabled = False
self._referenced_entities: set[str] | None = None
self._referenced_devices: set[str] | None = None
self._logger = LOGGER
self._variables = variables
self._trigger_variables = trigger_variables
@ -478,7 +482,7 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
"""Return True if entity is on."""
return self._async_detach_triggers is not None or self._is_enabled
@property
@cached_property
def referenced_areas(self) -> set[str]:
"""Return a set of referenced areas."""
return self.action_script.referenced_areas
@ -490,12 +494,9 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
return None
return cast(str, self._blueprint_inputs[CONF_USE_BLUEPRINT][CONF_PATH])
@property
@cached_property
def referenced_devices(self) -> set[str]:
"""Return a set of referenced devices."""
if self._referenced_devices is not None:
return self._referenced_devices
referenced = self.action_script.referenced_devices
if self._cond_func is not None:
@ -505,15 +506,11 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
for conf in self._trigger_config:
referenced |= set(_trigger_extract_devices(conf))
self._referenced_devices = referenced
return referenced
@property
@cached_property
def referenced_entities(self) -> set[str]:
"""Return a set of referenced entities."""
if self._referenced_entities is not None:
return self._referenced_entities
referenced = self.action_script.referenced_entities
if self._cond_func is not None:
@ -524,7 +521,6 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
for entity_id in _trigger_extract_entities(conf):
referenced.add(entity_id)
self._referenced_entities = referenced
return referenced
async def async_added_to_hass(self) -> None:

View File

@ -5,7 +5,7 @@ from abc import ABC, abstractmethod
import asyncio
from dataclasses import dataclass
import logging
from typing import Any, cast
from typing import TYPE_CHECKING, Any, cast
import voluptuous as vol
@ -72,6 +72,12 @@ from .const import (
from .helpers import async_get_blueprints
from .trace import trace_script
if TYPE_CHECKING:
from functools import cached_property
else:
from homeassistant.backports.functools import cached_property
SCRIPT_SERVICE_SCHEMA = vol.Schema(dict)
SCRIPT_TURN_ONOFF_SCHEMA = make_entity_service_schema(
{vol.Optional(ATTR_VARIABLES): {str: cv.match_all}}
@ -381,7 +387,7 @@ class BaseScriptEntity(ToggleEntity, ABC):
raw_config: ConfigType | None
@property
@cached_property
@abstractmethod
def referenced_areas(self) -> set[str]:
"""Return a set of referenced areas."""
@ -391,12 +397,12 @@ class BaseScriptEntity(ToggleEntity, ABC):
def referenced_blueprint(self) -> str | None:
"""Return referenced blueprint or None."""
@property
@cached_property
@abstractmethod
def referenced_devices(self) -> set[str]:
"""Return a set of referenced devices."""
@property
@cached_property
@abstractmethod
def referenced_entities(self) -> set[str]:
"""Return a set of referenced entities."""
@ -426,7 +432,7 @@ class UnavailableScriptEntity(BaseScriptEntity):
"""Return the name of the entity."""
return self._name
@property
@cached_property
def referenced_areas(self) -> set[str]:
"""Return a set of referenced areas."""
return set()
@ -436,12 +442,12 @@ class UnavailableScriptEntity(BaseScriptEntity):
"""Return referenced blueprint or None."""
return None
@property
@cached_property
def referenced_devices(self) -> set[str]:
"""Return a set of referenced devices."""
return set()
@property
@cached_property
def referenced_entities(self) -> set[str]:
"""Return a set of referenced entities."""
return set()
@ -509,7 +515,7 @@ class ScriptEntity(BaseScriptEntity, RestoreEntity):
"""Return true if script is on."""
return self.script.is_running
@property
@cached_property
def referenced_areas(self) -> set[str]:
"""Return a set of referenced areas."""
return self.script.referenced_areas
@ -521,12 +527,12 @@ class ScriptEntity(BaseScriptEntity, RestoreEntity):
return None
return self._blueprint_inputs[CONF_USE_BLUEPRINT][CONF_PATH]
@property
@cached_property
def referenced_devices(self) -> set[str]:
"""Return a set of referenced devices."""
return self.script.referenced_devices
@property
@cached_property
def referenced_entities(self) -> set[str]:
"""Return a set of referenced entities."""
return self.script.referenced_entities

View File

@ -12,7 +12,7 @@ from functools import partial
import itertools
import logging
from types import MappingProxyType
from typing import Any, TypedDict, TypeVar, cast
from typing import TYPE_CHECKING, Any, TypedDict, TypeVar, cast
import voluptuous as vol
@ -101,6 +101,12 @@ from .trace import (
from .trigger import async_initialize_triggers, async_validate_trigger_config
from .typing import UNDEFINED, ConfigType, UndefinedType
if TYPE_CHECKING:
from functools import cached_property
else:
from homeassistant.backports.functools import cached_property
# mypy: allow-untyped-calls, allow-untyped-defs, no-check-untyped-defs
_T = TypeVar("_T")
@ -1289,9 +1295,6 @@ class Script:
self._choose_data: dict[int, _ChooseData] = {}
self._if_data: dict[int, _IfData] = {}
self._parallel_scripts: dict[int, list[Script]] = {}
self._referenced_entities: set[str] | None = None
self._referenced_devices: set[str] | None = None
self._referenced_areas: set[str] | None = None
self.variables = variables
self._variables_dynamic = template.is_complex(variables)
if self._variables_dynamic:
@ -1362,15 +1365,12 @@ class Script:
"""Return true if the current mode support max."""
return self.script_mode in (SCRIPT_MODE_PARALLEL, SCRIPT_MODE_QUEUED)
@property
@cached_property
def referenced_areas(self) -> set[str]:
"""Return a set of referenced areas."""
if self._referenced_areas is not None:
return self._referenced_areas
self._referenced_areas = set()
Script._find_referenced_areas(self._referenced_areas, self.sequence)
return self._referenced_areas
referenced_areas: set[str] = set()
Script._find_referenced_areas(referenced_areas, self.sequence)
return referenced_areas
@staticmethod
def _find_referenced_areas(
@ -1402,15 +1402,12 @@ class Script:
for script in step[CONF_PARALLEL]:
Script._find_referenced_areas(referenced, script[CONF_SEQUENCE])
@property
@cached_property
def referenced_devices(self) -> set[str]:
"""Return a set of referenced devices."""
if self._referenced_devices is not None:
return self._referenced_devices
self._referenced_devices = set()
Script._find_referenced_devices(self._referenced_devices, self.sequence)
return self._referenced_devices
referenced_devices: set[str] = set()
Script._find_referenced_devices(referenced_devices, self.sequence)
return referenced_devices
@staticmethod
def _find_referenced_devices(
@ -1452,15 +1449,12 @@ class Script:
for script in step[CONF_PARALLEL]:
Script._find_referenced_devices(referenced, script[CONF_SEQUENCE])
@property
@cached_property
def referenced_entities(self) -> set[str]:
"""Return a set of referenced entities."""
if self._referenced_entities is not None:
return self._referenced_entities
self._referenced_entities = set()
Script._find_referenced_entities(self._referenced_entities, self.sequence)
return self._referenced_entities
referenced_entities: set[str] = set()
Script._find_referenced_entities(referenced_entities, self.sequence)
return referenced_entities
@staticmethod
def _find_referenced_entities(