Add numeric fast path for template result parsing (#175402)

This commit is contained in:
Franck Nijhof
2026-07-08 03:30:10 -04:00
committed by GitHub
parent 985ef60d8a
commit 715c355fda
2 changed files with 31 additions and 1 deletions
+24 -1
View File
@@ -239,8 +239,31 @@ RESULT_WRAPPERS: dict[type, type] = {kls: gen_result_wrapper(kls) for kls in _ty
RESULT_WRAPPERS[tuple] = TupleWrapper
@lru_cache(maxsize=EVAL_CACHE_SIZE)
def _parse_result(render_result: str) -> Any:
"""Parse a rendered result.
Continuously changing numeric results, like sensor values, produce
a new string on every render and would always miss the eval cache,
paying for a full literal_eval. Convert them directly instead.
Anything the fast path cannot convert falls through to the cached
path, which handles the edge cases ("", ".", "+") identically.
"""
if _IS_NUMERIC.match(render_result):
if "." in render_result:
try:
return float(render_result)
except ValueError:
pass
else:
try:
return int(render_result)
except ValueError:
pass
return _cached_parse_result(render_result)
@lru_cache(maxsize=EVAL_CACHE_SIZE)
def _cached_parse_result(render_result: str) -> Any:
"""Parse a result and cache the result."""
# lru_cache does not memoize raised exceptions. The most common template
# results, plain string states such as "on", "off" or "unavailable", are
+7
View File
@@ -906,6 +906,13 @@ async def test_parse_result(hass: HomeAssistant) -> None:
("-1.0", -1.0),
("+1", 1),
("5.", 5.0),
("-0", 0),
("-0.0", -0.0),
("+", "+"),
("-", "-"),
(".", "."),
# Exceeds the int digit limit for both int() and literal_eval
("9" * 5000, "9" * 5000),
("123_123_123", "123_123_123"),
# ("+48100200300", "+48100200300"), # phone number
("010", "010"),