Skip to content

Commit d134dea

Browse files
committed
gh-146448: fix t-string parser truncating expression at != with format spec
1 parent 4d0e8ee commit d134dea

3 files changed

Lines changed: 22 additions & 2 deletions

File tree

Lib/test/test_tstring.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,5 +287,14 @@ def test_triple_quoted(self):
287287
)
288288
self.assertEqual(fstring(t), "\n Hello,\n Python\n ")
289289

290+
def test_not_equal_with_format_spec(self):
291+
# gh-146448: != in expression with format spec should not be
292+
# confused with the ! conversion specifier
293+
t = t"{0!=0:}"
294+
self.assertTStringEqual(t, ("", ""), [(False, "0!=0")])
295+
296+
t = t"{0!=0:s}"
297+
self.assertTStringEqual(t, ("", ""), [(False, "0!=0", None, "s")])
298+
290299
if __name__ == '__main__':
291300
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix template string parser incorrectly truncating the ``Interpolation.str``
2+
attribute when the expression contains ``!=`` followed by a format spec.

Parser/lexer/lexer.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,8 +1250,17 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
12501250
goto again; /* Read next line */
12511251
}
12521252

1253-
/* Punctuation character */
1254-
int is_punctuation = (c == ':' || c == '}' || c == '!' || c == '{');
1253+
/* Punctuation character.
1254+
* '!' is only treated as f-string/t-string punctuation (conversion
1255+
* specifier) when not followed by '=' (which would make it '!='). */
1256+
int is_punctuation = (c == ':' || c == '}' || c == '{');
1257+
if (c == '!') {
1258+
int ahead = tok_nextc(tok);
1259+
tok_backup(tok, ahead);
1260+
if (ahead != '=') {
1261+
is_punctuation = 1;
1262+
}
1263+
}
12551264
if (is_punctuation && INSIDE_FSTRING(tok) && INSIDE_FSTRING_EXPR(current_tok)) {
12561265
/* This code block gets executed before the curly_bracket_depth is incremented
12571266
* by the `{` case, so for ensuring that we are on the 0th level, we need

0 commit comments

Comments
 (0)