Skip to content

Commit a4abf29

Browse files
authored
fix(workflows): reject a condition that is spliced into text, not evaluated (#4292)
`evaluate_expression` takes its typed fast path only when the whole string is exactly one `{{ ... }}` block. Anything else goes to `_interpolate_expressions`, which substitutes each block into the surrounding text and returns a *string*; `evaluate_condition` then coerces that with `bool()`. So a condition whose braces do not cover the whole expression is always true: {{ inputs.ready }} and {{ inputs.count > 100 }} -> "False and False" -> True not {{ inputs.ready }} -> "not False" -> True {{ inputs.count }} > 100 -> "0 > 100" -> True Each reads as a real comparison, each validates clean today, and each takes `then` on every run — a `while`/`do-while` written that way spins to `max_iterations`. The three validators already told authors the condition "is not a single complete '{{ }}' block", and nothing checked that property: `condition_is_never_evaluated` asks only whether *some* `{{` exists and closes. `condition_is_interpolated_to_text` derives the answer from `_is_single_expression` — the same predicate the fast path uses — rather than restating it, so the check cannot drift from the behaviour it predicts. It yields to both existing faults, which keep their own message and advice, and it offers no paste-ready correction: there is no single right rewrite of `{{ a }} and {{ b }}`, because only the author knows the grouping meant.
1 parent 041faee commit a4abf29

5 files changed

Lines changed: 155 additions & 0 deletions

File tree

src/specify_cli/workflows/expressions.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,42 @@ def condition_is_never_evaluated(condition: Any) -> bool:
785785
return _first_unclosable_block(stripped) == "verbatim"
786786

787787

788+
def condition_is_interpolated_to_text(condition: Any) -> bool:
789+
"""True when *condition* holds ``{{ }}`` blocks but is spliced into text, not evaluated.
790