Skip to content

Commit 9e23755

Browse files
authored
Ignore Jinja import filenames (#1307)
1 parent a0b9bed commit 9e23755

2 files changed

Lines changed: 71 additions & 3 deletions

File tree

custom_components/spook/entity_filtering.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,32 @@ def _is_concatenated_template_match(template_str: str, match: re.Match[str]) ->
418418
return before_literal.endswith("~") or after_literal.startswith("~")
419419

420420

421+
def _is_jinja_import_match(template_str: str, match: re.Match[str]) -> bool:
422+
"""Return if a quoted entity-like literal is a Jinja import filename."""
423+
groups = match.groups()
424+
if len(groups) == _STATES_DOMAIN_ENTITY_GROUPS:
425+
return False
426+
427+
entity_start, entity_end = match.span(1)
428+
block_start = template_str.rfind("{%", 0, entity_start)
429+
expression_start = template_str.rfind("{{", 0, entity_start)
430+
if block_start == -1 or expression_start > block_start:
431+
return False
432+
433+
block_end = template_str.find("%}", entity_end)
434+
expression_end = template_str.find("}}", entity_end)
435+
if block_end == -1 or (expression_end != -1 and expression_end < block_end):
436+
return False
437+
438+
block = template_str[block_start : block_end + 2]
439+
return bool(
440+
re.match(
441+
r"\{%-?\s*(?:from\s+['\"][^'\"]+['\"]\s+import|import\s+['\"][^'\"]+['\"]\s+as)",
442+
block,
443+
)
444+
)
445+
446+
421447
def _is_string_method_argument_match(template_str: str, match: re.Match[str]) -> bool:
422448
"""Return if an entity-like literal is used as a string method argument."""
423449
groups = match.groups()
@@ -473,9 +499,11 @@ def extract_entities_from_template_regex(
473499

474500
for pattern in ENTITY_ID_TEMPLATE_PATTERNS:
475501
for match in re.finditer(pattern, template_str, re.IGNORECASE):
476-
if _is_concatenated_template_match(
477-
template_str, match
478-
) or _is_string_method_argument_match(template_str, match):
502+
if (
503+
_is_concatenated_template_match(template_str, match)
504+
or _is_jinja_import_match(template_str, match)
505+
or _is_string_method_argument_match(template_str, match)
506+
):
479507
continue
480508

481509
entity_id = _entity_id_from_template_match(match)

tests/ectoplasms/automation/repairs/test_unknown_entity_references.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,46 @@ async def test_value_template_ignores_concatenated_entity_id_literal(
6666
assert await extract_entities_from_value(hass, template) == set()
6767

6868

69+
async def test_value_template_ignores_jinja_import_filename(
70+
hass: HomeAssistant,
71+
) -> None:
72+
"""Jinja import filenames are not entity references."""
73+
template = "{% from 'date.jinja' import how_about_now %}{{ how_about_now() }}"
74+
75+
assert await extract_entities_from_value(hass, template) == set()
76+
77+
78+
async def test_value_template_ignores_jinja_import_as_filename(
79+
hass: HomeAssistant,
80+
) -> None:
81+
"""Jinja import-as filenames are not entity references."""
82+
template = "{% import 'date.jinja' as date_helpers %}{{ date_helpers.now() }}"
83+
84+
assert await extract_entities_from_value(hass, template) == set()
85+
86+
87+
async def test_value_template_ignores_whitespace_control_jinja_import_filename(
88+
hass: HomeAssistant,
89+
) -> None:
90+
"""Jinja import filenames with whitespace control are not entity references."""
91+
template = "{%- from 'date.jinja' import how_about_now -%}{{ how_about_now() }}"
92+
93+
assert await extract_entities_from_value(hass, template) == set()
94+
95+
96+
async def test_value_template_keeps_entity_reference_between_jinja_blocks(
97+
hass: HomeAssistant,
98+
) -> None:
99+
"""Entity references in expression blocks are not treated as import filenames."""
100+
template = (
101+
"{% from 'date.jinja' import how_about_now %}"
102+
"{{ states('light.kitchen') }}"
103+
"{% set finished = true %}"
104+
)
105+
106+
assert await extract_entities_from_value(hass, template) == {"light.kitchen"}
107+
108+
69109
async def test_value_template_ignores_entity_id_prefix_string_match(
70110
hass: HomeAssistant,
71111
) -> None:

0 commit comments

Comments
 (0)