https://github.com/python/cpython/commit/b451516aa69df357af829c6a9f773fb51862b5b8
commit: b451516aa69df357af829c6a9f773fb51862b5b8
branch: main
author: sobolevn <[email protected]>
committer: sobolevn <[email protected]>
date: 2025-04-30T19:20:44+03:00
summary:
gh-133197: Improve error message for `ft""` and `bt""` cases (#133202)
files:
M Lib/test/test_syntax.py
M Parser/lexer/lexer.c
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 55492350d00714..7ef4b735fcb805 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -1877,6 +1877,22 @@
Traceback (most recent call last):
SyntaxError: cannot assign to f-string expression here. Maybe you meant '=='
instead of '='?
+>>> ft'abc'
+Traceback (most recent call last):
+SyntaxError: can't use 'f' and 't' string prefixes together
+
+>>> tf"{x=}"
+Traceback (most recent call last):
+SyntaxError: can't use 'f' and 't' string prefixes together
+
+>>> tb''
+Traceback (most recent call last):
+SyntaxError: can't use 'b' and 't' string prefixes together
+
+>>> bt"text"
+Traceback (most recent call last):
+SyntaxError: can't use 'b' and 't' string prefixes together
+
>>> t'{x}' = 42
Traceback (most recent call last):
SyntaxError: cannot assign to t-string expression here. Maybe you meant '=='
instead of '='?
diff --git a/Parser/lexer/lexer.c b/Parser/lexer/lexer.c
index ca01cab9937a85..98adf7447c5626 100644
--- a/Parser/lexer/lexer.c
+++ b/Parser/lexer/lexer.c
@@ -648,7 +648,7 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode*
current_tok, struct t
/* Process the various legal combinations of b"", r"", u"", and f"". */
int saw_b = 0, saw_r = 0, saw_u = 0, saw_f = 0, saw_t = 0;
while (1) {
- if (!(saw_b || saw_u || saw_f || saw_t) && (c == 'b' || c == 'B'))
+ if (!(saw_b || saw_u || saw_f) && (c == 'b' || c == 'B'))
saw_b = 1;
/* Since this is a backwards compatibility support literal we don't
want to support it in arbitrary order like byte literals. */
@@ -660,10 +660,10 @@ tok_get_normal_mode(struct tok_state *tok,
tokenizer_mode* current_tok, struct t
else if (!(saw_r || saw_u) && (c == 'r' || c == 'R')) {
saw_r = 1;
}
- else if (!(saw_f || saw_b || saw_u || saw_t) && (c == 'f' || c ==
'F')) {
+ else if (!(saw_f || saw_b || saw_u) && (c == 'f' || c == 'F')) {
saw_f = 1;
}
- else if (!(saw_t || saw_b || saw_u || saw_f) && (c == 't' || c ==
'T')) {
+ else if (!(saw_t || saw_u) && (c == 't' || c == 'T')) {
saw_t = 1;
}
else {
@@ -671,6 +671,20 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode*
current_tok, struct t
}
c = tok_nextc(tok);
if (c == '"' || c == '\'') {
+ if (saw_b && saw_t) {
+ return MAKE_TOKEN(_PyTokenizer_syntaxerror_known_range(
+ tok, (int)(tok->start + 1 - tok->line_start),
+ (int)(tok->cur - tok->line_start),
+ "can't use 'b' and 't' string prefixes together"));
+ }
+ if (saw_f && saw_t) {
+ return MAKE_TOKEN(_PyTokenizer_syntaxerror_known_range(
+ tok, (int)(tok->start + 1 - tok->line_start),
+ (int)(tok->cur - tok->line_start),
+ "can't use 'f' and 't' string prefixes together"));
+ }
+
+ // Handle valid f or t string creation:
if (saw_f || saw_t) {
goto f_string_quote;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]