Add is_number template filter and function (#56705)

pull/54039/head
Erik Montnemery 2021-09-27 10:47:57 +02:00 committed by GitHub
parent e4dc646237
commit 14a1bb423c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 0 deletions

View File

@ -1370,6 +1370,17 @@ def forgiving_float(value):
return value
def is_number(value):
"""Try to convert value to a float."""
try:
fvalue = float(value)
except (ValueError, TypeError):
return False
if math.isnan(fvalue) or math.isinf(fvalue):
return False
return True
def regex_match(value, find="", ignorecase=False):
"""Match value using regex."""
if not isinstance(value, str):
@ -1575,6 +1586,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
self.filters["bitwise_and"] = bitwise_and
self.filters["bitwise_or"] = bitwise_or
self.filters["ord"] = ord
self.filters["is_number"] = is_number
self.globals["log"] = logarithm
self.globals["sin"] = sine
self.globals["cos"] = cosine
@ -1597,6 +1609,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
self.globals["urlencode"] = urlencode
self.globals["max"] = max
self.globals["min"] = min
self.globals["is_number"] = is_number
self.tests["match"] = regex_match
self.tests["search"] = regex_search

View File

@ -220,6 +220,41 @@ def test_float(hass):
)
@pytest.mark.parametrize(
"value, expected",
[
(0, True),
(0.0, True),
("0", True),
("0.0", True),
(True, True),
(False, True),
("True", False),
("False", False),
(None, False),
("None", False),
("horse", False),
(math.pi, True),
(math.nan, False),
(math.inf, False),
("nan", False),
("inf", False),
],
)
def test_isnumber(hass, value, expected):
"""Test is_number."""
assert (
template.Template("{{ is_number(value) }}", hass).async_render({"value": value})
== expected
)
assert (
template.Template("{{ value | is_number }}", hass).async_render(
{"value": value}
)
== expected
)
def test_rounding_value(hass):
"""Test rounding value."""
hass.states.async_set("sensor.temperature", 12.78)