fix(functemplate): empty ${} inside a call argument truncates the argument list#6846
Open
chuenchen309 wants to merge 1 commit into
Open
Conversation
…ument list
`Parser.parse_symbol` handled "no closing brace" and "empty identifier" in
the same branch, emitting `${` as literal text without advancing past the
closing brace. The unconsumed `}` was then read by `parse_argument_list` as
the enclosing call's terminator, so the argument list was cut short and the
remainder of the template leaked out as raw text:
%foo{a${}b} -> Call('foo', ['a${']) + 'b}' (was 'A${b}' evaluated)
%foo{a${}b,baz} -> parsed as one argument + raw 'b,baz}'
At the top level `}` is not a terminator, which is why `a ${} b` parsed
correctly and the existing test did not catch this.
Split the two cases so an empty identifier consumes through the closing
brace, keeping `${}` as literal text in both contexts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chuenchen309
force-pushed
the
fix/functemplate-empty-braces-in-call-arg
branch
from
July 16, 2026 12:18
48af8b8 to
e71110a
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #6846 +/- ##
=======================================
Coverage 75.60% 75.60%
=======================================
Files 163 163
Lines 21299 21302 +3
Branches 3358 3359 +1
=======================================
+ Hits 16103 16106 +3
Misses 4406 4406
Partials 790 790
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A path format like
%upper{a${}b}evaluates toA${b}instead ofA${}B, and%if{1,a${}b,c}collapses toa${}b— the rest of the template leaks out as literal text.Cause
Parser.parse_symbolhandles "no closing brace found" and "identifier is empty" in the same branch:Both emit
${as literal text, but the two cases need different amounts of input consumed. With an empty identifier the closing brace exists and is left unconsumed, soparse_argument_listreads it as the enclosing call's terminator. The argument list ends early and the remainder becomes raw text:At the top level
}is not a terminator, soa ${} bparses correctly — which is why the existingtest_empty_braces_symbolpasses and this went unnoticed. Only nesting inside a function-call argument triggers it.Fix
Split the branch so an empty identifier consumes through the closing brace.
${}stays literal text in both contexts; thecloser == -1path is unchanged.Verification
Both new tests fail on master (
assert 2 == 1— the leaked'b,baz}'part) and pass with the fix. Fulltest/util/test_functemplate.pypasses (49/49), as doestest/test_library.py(170 passed).ruff check,ruff format --check,mypy, anddocstrfmt --checkon the changelog are all clean.AI disclosure: drafted with Claude Code (Opus 4.8), including the root-cause trace and tests. I ran the repro and the full test suite locally and reviewed the diff before opening this.