Speed up validating domains in templates (#92975)

This path gets called quite a bit since most templates
access the state via states.DOMAIN...
This commit is contained in:
J. Nick Koston 2023-05-12 21:57:51 +09:00 committed by GitHub
parent 5a7c3aaa2d
commit 24284fe379
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 2 deletions

View file

@ -161,9 +161,19 @@ def split_entity_id(entity_id: str) -> tuple[str, str]:
return domain, object_id
VALID_ENTITY_ID = re.compile(r"^(?!.+__)(?!_)[\da-z_]+(?<!_)\.(?!_)[\da-z_]+(?<!_)$")
_OBJECT_ID = r"(?!_)[\da-z_]+(?<!_)"
_DOMAIN = r"(?!.+__)" + _OBJECT_ID
VALID_DOMAIN = re.compile(r"^" + _DOMAIN + r"$")
VALID_ENTITY_ID = re.compile(r"^" + _DOMAIN + r"\." + _OBJECT_ID + r"$")
@functools.lru_cache(64)
def valid_domain(domain: str) -> bool:
"""Test if a domain a valid format."""
return VALID_DOMAIN.match(domain) is not None
@functools.lru_cache(64)
def valid_entity_id(entity_id: str) -> bool:
"""Test if an entity ID is a valid format.

View file

@ -63,6 +63,7 @@ from homeassistant.core import (
State,
callback,
split_entity_id,
valid_domain,
valid_entity_id,
)
from homeassistant.exceptions import TemplateError
@ -796,7 +797,7 @@ class AllStates:
if name in _RESERVED_NAMES:
return None
if not valid_entity_id(f"{name}.entity"):
if not valid_domain(name):
raise TemplateError(f"Invalid domain name '{name}'")
return _domain_states(self._hass, name)

View file

@ -1384,6 +1384,32 @@ def test_valid_entity_id() -> None:
assert ha.valid_entity_id(valid), valid
def test_valid_domain() -> None:
"""Test valid domain."""
for invalid in [
"_light",
".kitchen",
".light.kitchen",
"light_.kitchen",
"._kitchen",
"light.",
"light.kitchen__ceiling",
"light.kitchen_yo_",
"light.kitchen.",
"Light",
]:
assert not ha.valid_domain(invalid), invalid
for valid in [
"1",
"1light",
"a",
"input_boolean",
"light",
]:
assert ha.valid_domain(valid), valid
async def test_additional_data_in_core_config(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None: