]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-133197: Improve error message for `ft""` and `bt""` cases (#133202)
authorsobolevn <mail@sobolevn.me>
Wed, 30 Apr 2025 16:20:44 +0000 (19:20 +0300)
committerGitHub <noreply@github.com>
Wed, 30 Apr 2025 16:20:44 +0000 (19:20 +0300)
Lib/test/test_syntax.py
Parser/lexer/lexer.c

index 55492350d00714420162ab67dde4ffe4a0b772be..7ef4b735fcb8054de8b51413b7630f0719cb3e6b 100644 (file)
@@ -1877,6 +1877,22 @@ SyntaxError: cannot assign to f-string expression here. Maybe you meant '==' ins
 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 '='?
index ca01cab9937a85ce26bde784b4f6df3385b1a00f..98adf7447c56269c170508b5877735f6f8c493bb 100644 (file)
@@ -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;
                 }