gh-154719: Preserve trailing whitespace in t-string interpolation expressions - #154762
gh-154719: Preserve trailing whitespace in t-string interpolation expressions#154762lpyu001 wants to merge 5 commits into
Conversation
| } | ||
| len--; | ||
| } | ||
| /* The debug marker may be absent from reconstructed lexer metadata. */ |
There was a problem hiding this comment.
I am not sure this comment is accurate: after the lexer fix, removing comments can never drop the debug = (the marker cannot be inside a comment and the metadata always extends past it), so IIUC this branch is only reachable via things like a line continuation right after the =. Can you adjust the comment or add a test that reaches this branch?
There was a problem hiding this comment.
Thanks, I will address it.
There was a problem hiding this comment.
A valid case that reached
this branch is an explicit line continuation after the debug marker:
t'''{value =\
}'''The first patch returned "value =\\\n" as the expression. This conflicts with the [Interpolation.expression documentation(https://docs.python.org/3.16/library/string.templatelib.html#string.templatelib.Interpolation.expression),which says the expression ends before =. The expected expression is "value ".
I updated the code to strip explicit line continuations after the debug marker and added regression tests.
|
|
||
| // Copy escaped characters without interpreting the escaped | ||
| // character as a quote or comment marker. | ||
| if (ch == '\\') { |
There was a problem hiding this comment.
The lexer fix also changes the debug text for f-strings (_PyLexer_set_ftstring_expr is shared when in_debug is set), e.g. a debug expression combining a comment with an escaped quote was truncated before this. Can you add a test for the f-string case in test_fstring as well? Maybe worth mentioning f-strings in the NEWS entry too.
There was a problem hiding this comment.
I have added the tests and updated the NEWS file
1.
Interpolation.expressiondid not match its documented contractDoc/library/string.templatelib.rststates that, for interpolations created by t-string literals,expressionisWhitespace after
{was preserved, but whitespace before},!,:or a debug=was removed:The asymmetry is not documented anywhere: leading whitespace was kept, trailing whitespace was dropped.
2.
ast.unparse()could emit code that no longer parsesWhen the interpolation ended with an explicit line continuation, stripping the trailing whitespace also removed the newline that terminated it, leaving a dangling backslash in
Interpolation.str:Root cause
_strip_interpolation_expr()inParser/action_helpers.cwas applied to every interpolation, not just debug ones. It walked backwards over the lexer metadata removing every trailing whitespace character and=, which is only correct forthe debug (
=) form, where the trailing=and the text after it belong to the debug text rather than to the expression.Solution
=and discard only the=itself plus the whitespace and explicit line continuations that follow it. Per the documentation the expression ends before the=, sot"""{value =\<newline>}"""yields'value ', and the\<newline>stays in the debug text.