https://github.com/python/cpython/commit/2f8b08da475152adea59b6bf98e2d0cb73dd8a59 commit: 2f8b08da475152adea59b6bf98e2d0cb73dd8a59 branch: main author: Pablo Galindo Salgado <pablog...@gmail.com> committer: ambv <luk...@langa.pl> date: 2025-04-18T14:30:04+02:00 summary:
gh-129958: Properly disallow newlines in format specs in single-quoted f-strings (GH-130063) files: A Misc/NEWS.d/next/Core_and_Builtins/2025-02-13-00-14-24.gh-issue-129958.Uj7lyY.rst M Lib/test/test_fstring.py M Lib/test/test_tokenize.py M Parser/lexer/lexer.c diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 5974024c170cef..e75e7db378cef1 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1795,6 +1795,31 @@ def test_gh129093(self): self.assertEqual(f'{f'{1!=2=}'=}', "f'{1!=2=}'='1!=2=True'") self.assertEqual(f'{f'{1 != 2=}'=}', "f'{1 != 2=}'='1 != 2=True'") + def test_newlines_in_format_specifiers(self): + cases = [ + """f'{1:d\n}'""", + """f'__{ + 1:d + }__'""", + '''f"{value:. + {'2f'}}"''', + '''f"{value: + {'.2f'}f}"''', + '''f"{value: + #{'x'}}"''', + ] + self.assertAllRaise(SyntaxError, "f-string: newlines are not allowed in format specifiers", cases) + + valid_cases = [ + """f'''__{ + 1:d + }__'''""", + """f'''{1:d\n}'''""", + ] + + for case in valid_cases: + compile(case, "<string>", "exec") + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 4e05a38394cdc1..2d41a5e5ac0697 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -605,22 +605,6 @@ def test_string(self): OP '}' (6, 0) (6, 1) FSTRING_MIDDLE '__' (6, 1) (6, 3) FSTRING_END "'''" (6, 3) (6, 6) - """) - self.check_tokenize("""\ -f'__{ - x:d -}__'""", """\ - FSTRING_START "f'" (1, 0) (1, 2) - FSTRING_MIDDLE '__' (1, 2) (1, 4) - OP '{' (1, 4) (1, 5) - NL '\\n' (1, 5) (1, 6) - NAME 'x' (2, 4) (2, 5) - OP ':' (2, 5) (2, 6) - FSTRING_MIDDLE 'd' (2, 6) (2, 7) - NL '\\n' (2, 7) (2, 8) - OP '}' (3, 0) (3, 1) - FSTRING_MIDDLE '__' (3, 1) (3, 3) - FSTRING_END "'" (3, 3) (3, 4) """) self.check_tokenize("""\ @@ -2471,21 +2455,6 @@ def test_string(self): RBRACE '}' (6, 0) (6, 1) FSTRING_MIDDLE '__' (6, 1) (6, 3) FSTRING_END "'''" (6, 3) (6, 6) - """) - - self.check_tokenize("""\ -f'__{ - x:d -}__'""", """\ - FSTRING_START "f'" (1, 0) (1, 2) - FSTRING_MIDDLE '__' (1, 2) (1, 4) - LBRACE '{' (1, 4) (1, 5) - NAME 'x' (2, 4) (2, 5) - COLON ':' (2, 5) (2, 6) - FSTRING_MIDDLE 'd' (2, 6) (2, 7) - RBRACE '}' (3, 0) (3, 1) - FSTRING_MIDDLE '__' (3, 1) (3, 3) - FSTRING_END "'" (3, 3) (3, 4) """) def test_function(self): @@ -3041,6 +3010,10 @@ def get_tokens(string): "'''sdfsdf''", "("*1000+"a"+")"*1000, "]", + """\ + f'__{ + x:d + }__'""", ]: with self.subTest(case=case): self.assertRaises(tokenize.TokenError, get_tokens, case) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-13-00-14-24.gh-issue-129958.Uj7lyY.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-13-00-14-24.gh-issue-129958.Uj7lyY.rst new file mode 100644 index 00000000000000..c0fa76c89e4c4e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-13-00-14-24.gh-issue-129958.Uj7lyY.rst @@ -0,0 +1,2 @@ +Fix a bug that was allowing newlines inconsitently in format specifiers for +single-quoted f-strings. Patch by Pablo Galindo. diff --git a/Parser/lexer/lexer.c b/Parser/lexer/lexer.c index 45604b197f43f2..5e68e5d035c545 100644 --- a/Parser/lexer/lexer.c +++ b/Parser/lexer/lexer.c @@ -1341,6 +1341,14 @@ tok_get_fstring_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct // it means that the format spec ends here and we should // return to the regular mode. if (in_format_spec && c == '\n') { + if (current_tok->f_string_quote_size == 1) { + return MAKE_TOKEN( + _PyTokenizer_syntaxerror( + tok, + "f-string: newlines are not allowed in format specifiers for single quoted f-strings" + ) + ); + } tok_backup(tok, c); TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; current_tok->in_format_spec = 0; _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com