]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-104658: Fix location of unclosed quote error for multiline f-strings (#104660)
authorPablo Galindo Salgado <Pablogsal@gmail.com>
Sat, 20 May 2023 13:07:05 +0000 (14:07 +0100)
committerGitHub <noreply@github.com>
Sat, 20 May 2023 13:07:05 +0000 (14:07 +0100)
Lib/test/test_fstring.py
Parser/tokenizer.c
Parser/tokenizer.h

index 58e2550715cecf49388f5c57097c2d8f8182836a..fcb12d25ff9dd6728afadb7beb976dba3f4d233c 100644 (file)
@@ -1558,7 +1558,21 @@ x = (
         self.assertAllRaise(SyntaxError, "unterminated f-string literal", ['f"', "f'"])
         self.assertAllRaise(SyntaxError, "unterminated triple-quoted f-string literal",
                             ['f"""', "f'''"])
-
+        # Ensure that the errors are reported at the correct line number.
+        data = '''\
+x = 1 + 1
+y = 2 + 2
+z = f"""
+sdfjnsdfjsdf
+sdfsdfs{1+
+2} dfigdf {3+
+4}sdufsd""
+'''
+        try:
+            compile(data, "?", "exec")
+        except SyntaxError as e:
+            self.assertEqual(e.text, 'z = f"""')
+            self.assertEqual(e.lineno, 3)
     def test_syntax_error_after_debug(self):
         self.assertAllRaise(SyntaxError, "f-string: expecting a valid expression after '{'",
                             [
index 91ffabac56c7b3f1efa082c936cf1e0bf74a0262..c5dc9e706fe474f9171fbb9d9e0da99dd742b5fb 100644 (file)
@@ -1124,7 +1124,7 @@ tok_underflow_interactive(struct tok_state *tok) {
 
 static int
 tok_underflow_file(struct tok_state *tok) {
-    if (tok->start == NULL) {
+    if (tok->start == NULL && !INSIDE_FSTRING(tok)) {
         tok->cur = tok->inp = tok->buf;
     }
     if (tok->decoding_state == STATE_INIT) {
@@ -2250,6 +2250,7 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
         the_current_tok->f_string_quote_size = quote_size;
         the_current_tok->f_string_start = tok->start;
         the_current_tok->f_string_multi_line_start = tok->line_start;
+        the_current_tok->f_string_line_start = tok->lineno;
         the_current_tok->f_string_start_offset = -1;
         the_current_tok->f_string_multi_line_start_offset = -1;
         the_current_tok->last_expr_buffer = NULL;
@@ -2580,7 +2581,9 @@ f_string_middle:
             tok->cur++;
             tok->line_start = current_tok->f_string_multi_line_start;
             int start = tok->lineno;
-            tok->lineno = tok->first_lineno;
+
+            tokenizer_mode *the_current_tok = TOK_GET_MODE(tok);
+            tok->lineno = the_current_tok->f_string_line_start;
 
             if (current_tok->f_string_quote_size == 3) {
                 return MAKE_TOKEN(syntaxerror(tok,
index 5e2171885ac75b4ee37c164828b07d4d756da7de..fd169cf3d1bab65aa44cf41fd4326fe3e6768d1b 100644 (file)
@@ -53,6 +53,7 @@ typedef struct _tokenizer_mode {
     int f_string_raw;
     const char* f_string_start;
     const char* f_string_multi_line_start;
+    int f_string_line_start;
 
     Py_ssize_t f_string_start_offset;
     Py_ssize_t f_string_multi_line_start_offset;