Skip to content

Commit 877056e

Browse files
committed
fix(policy): mypy narrowing for evaluator comparisons (homeassistant-ai#966)
`Predicate.value` is `Any | None` and `extract_path` returns `Any`, so `val == pv`, `val > pv`, etc. inherit `Any` and trip the project's `warn_return_any` mypy setting on functions declared `-> bool`. Wrap the comparison branches in `bool(...)` to make the narrowing explicit. Also guard the `regex` branch with `isinstance(pv, str)` so `re.search` receives a definite `str` instead of `Any | None`; a non-string regex value now returns False instead of raising TypeError at evaluation time, which is the only sensible behavior for a malformed pattern. No change to any test's expected outcome.
1 parent 5ea9581 commit 877056e

1 file changed

Lines changed: 9 additions & 5 deletions

File tree

src/ha_mcp/policy/evaluator.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,26 @@ def match_predicate(predicate: Predicate, args: dict[str, Any]) -> bool:
4040
pv = predicate.value
4141
match predicate.op:
4242
case "eq":
43-
return val == pv
43+
return bool(val == pv)
4444
case "neq":
45-
return val != pv
45+
return bool(val != pv)
4646
case "in":
4747
return val in (pv or [])
4848
case "not_in":
4949
return val not in (pv or [])
5050
# `regex` is re.search (substring match). Anchor with ^...$ for full-match.
5151
case "regex":
52-
return isinstance(val, str) and re.search(pv, val) is not None
52+
return (
53+
isinstance(val, str)
54+
and isinstance(pv, str)
55+
and re.search(pv, val) is not None
56+
)
5357
case "contains":
5458
return isinstance(val, (str, list, tuple, set)) and pv in val
5559
case "gt":
56-
return val > pv
60+
return bool(val > pv)
5761
case "lt":
58-
return val < pv
62+
return bool(val < pv)
5963
return False
6064

6165

0 commit comments

Comments
 (0)