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

View File

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

View File

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