From 5f9515f95e996134d33038bbb61df44436080c8c Mon Sep 17 00:00:00 2001 From: Arnesh Banerjee Date: Sat, 26 Sep 2026 11:45:39 +0530 Subject: [PATCH] [3.13] gh-154711: Strip comments after escaped quotes in f-string debug text When a replacement field ended with a string that had an escaped quote and was followed by a comment, the comment leaked into the debug f-string output. The comment detection loop in set_fstring_expr skips escaped characters, but the comment stripping loop did not. So an escaped quote left the scanner thinking it was still inside a string, and the comment was never removed. This makes the stripping loop skip escaped characters the same way the detection loop does. 3.14 and later already have this fix from gh-154719. --- Lib/test/test_fstring.py | 5 +++++ .../2026-07-30-14-40-00.gh-issue-154711.nUxYXc.rst | 3 +++ Parser/lexer/lexer.c | 13 +++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-07-30-14-40-00.gh-issue-154711.nUxYXc.rst diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index b47e906ce351c7..2acd49f3584513 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1664,6 +1664,11 @@ def __repr__(self): self.assertEqual(f'{" # nooo "=}', '" # nooo "=\' # nooo \'') self.assertEqual(f'{" \" # nooo \" "=}', '" \\" # nooo \\" "=\' " # nooo " \'') + # A real comment after a string that ends with an escaped quote must + # still be stripped (gh-154711). + self.assertEqual(f"{'\'' = # comment +}", "'\\'' = \n" + repr("'")) + self.assertEqual(f'{ # some comment goes here """hello"""=}', ' \n """hello"""=\'hello\'') self.assertEqual(f'{"""# this is not a comment diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-30-14-40-00.gh-issue-154711.nUxYXc.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-30-14-40-00.gh-issue-154711.nUxYXc.rst new file mode 100644 index 00000000000000..58ad001d3befb7 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-30-14-40-00.gh-issue-154711.nUxYXc.rst @@ -0,0 +1,3 @@ +Fix a bug where a comment placed after a string that ends with an escaped +quote could leak into the output of a debug f-string. Now the comment is +stripped as expected. diff --git a/Parser/lexer/lexer.c b/Parser/lexer/lexer.c index 38d3742f6e73d0..110f312498bdd5 100644 --- a/Parser/lexer/lexer.c +++ b/Parser/lexer/lexer.c @@ -162,6 +162,19 @@ set_fstring_expr(struct tok_state* tok, struct token *token, char c) { while (i < expression_size) { char ch = expression[i]; + // Copy escaped characters as-is. This keeps an escaped quote from + // flipping the in_string state, which would otherwise stop a real + // comment from being detected (see the detection loop above). + if (ch == '\\') { + result[j++] = ch; + i++; + if (i < expression_size) { + result[j++] = expression[i]; + i++; + } + continue; + } + // Handle string quotes if (ch == '"' || ch == '\'') { // See comment above to understand this part