mirror of
https://github.com/github/spec-kit.git
synced 2026-08-03 06:26:30 +08:00
fix(workflows): list-literal expression ignores trailing/empty commas (#3631)
A workflow list-literal expression with a trailing (or leading/double) comma —
'{{ [1, 2,] }}' — evaluated to [1, 2, None]: _split_top_level_commas returns a
trailing empty segment, which _evaluate_simple_expression resolves as an empty
dot-path to None. That silently widens membership tests and renders a stray
None in joins. Python and Jinja2 both tolerate trailing commas.
Drop whitespace-empty segments from the comprehension. An intentional
empty-string element ('') survives because its segment strips to "''" (truthy),
so ['', 'a'] is preserved. Completes the quoted-comma handling from #3134.
Test: [1, 2,] and [1,, 2] -> [1, 2]; ['', 'a'] -> ['', 'a'] (fails before:
trailing None).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -535,6 +535,10 @@ def _evaluate_simple_expression(expr: str, namespace: dict[str, Any]) -> Any:
|
||||
items = [
|
||||
_evaluate_simple_expression(i.strip(), namespace)
|
||||
for i in _split_top_level_commas(inner)
|
||||
# Drop empty segments from trailing/leading/double commas ([1, 2,] ->
|
||||
# [1, 2], not [1, 2, None]). An intentional empty-string element
|
||||
# ('') strips to "''" (truthy), so ['', 'a'] is preserved.
|
||||
if i.strip()
|
||||
]
|
||||
return items
|
||||
|
||||
|
||||
@@ -404,6 +404,17 @@ class TestExpressions:
|
||||
assert evaluate_expression('{{ [["a", "b"], "c"] }}', ctx) == [["a", "b"], "c"]
|
||||
assert evaluate_expression("{{ [[1, 2], [3, 4]] }}", ctx) == [[1, 2], [3, 4]]
|
||||
|
||||
def test_list_literal_ignores_trailing_and_empty_commas(self):
|
||||
from specify_cli.workflows.expressions import evaluate_expression
|
||||
from specify_cli.workflows.base import StepContext
|
||||
|
||||
ctx = StepContext()
|
||||
# A trailing comma must not append a spurious None element.
|
||||
assert evaluate_expression("{{ [1, 2,] }}", ctx) == [1, 2]
|
||||
assert evaluate_expression("{{ [1,, 2] }}", ctx) == [1, 2]
|
||||
# …but an intentional empty-string element is still preserved.
|
||||
assert evaluate_expression("{{ ['', 'a'] }}", ctx) == ["", "a"]
|
||||
|
||||
def test_operator_splitting_is_quote_aware(self):
|
||||
from specify_cli.workflows.expressions import (
|
||||
evaluate_condition,
|
||||
|
||||
Reference in New Issue
Block a user