mirror of https://github.com/astral-sh/ruff
Summary -- Fixes #20844 by refining the unsupported syntax error check for [PEP 701] f-strings before Python 3.12 to allow backslash escapes and escaped outer quotes in the format spec part of f-strings. These are only disallowed within the f-string expression part on earlier versions. Using the examples from the PR: ```pycon >>> f"{1:\x64}" '1' >>> f"{1:\"d\"}" Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: Invalid format specifier '"d"' for object of type 'int' ``` Note that the second case is a runtime error, but this is actually avoidable if you override `__format__`, so despite being pretty weird, this could actually be a valid use case. ```pycon >>> class C: ... def __format__(*args, **kwargs): return "<C>" ... >>> f"{C():\"d\"}" '<C>' ``` At first I thought narrowing the range we check to exclude the format spec would only work for escapes, but it turns out that cases like `f"{1:""}"` are already covered by an existing `ParseError`, so we can just narrow the range of both our escape and quote checks. Our comment check also seems to be working correctly because it's based on the actual tokens. A case like [this](https://play.ruff.rs/9f1c2ff2-cd8e-4ad7-9f40-56c0a524209f): ```python f"""{1:# }""" ``` doesn't include a comment token, instead the `#` is part of an `InterpolatedStringLiteralElement`. Test Plan -- New inline parser tests [PEP 701]: https://peps.python.org/pep-0701/ |
||
|---|---|---|
| .. | ||
| carriage_return | ||
| expression | ||
| fmt_on_off | ||
| fmt_skip | ||
| parentheses | ||
| pattern | ||
| range_formatting | ||
| statement | ||
| stub_files | ||
| .editorconfig | ||
| blank_line_before_class_docstring.options.json | ||
| blank_line_before_class_docstring.py | ||
| docstring.options.json | ||
| docstring.py | ||
| docstring_chaperones.py | ||
| docstring_code_examples.options.json | ||
| docstring_code_examples.py | ||
| docstring_code_examples_crlf.options.json | ||
| docstring_code_examples_crlf.py | ||
| docstring_code_examples_dynamic_line_width.options.json | ||
| docstring_code_examples_dynamic_line_width.py | ||
| docstring_newlines.py | ||
| docstring_non_visible_characters.py | ||
| docstring_tab_indentation.options.json | ||
| docstring_tab_indentation.py | ||
| empty_multiple_trailing_newlines.py | ||
| empty_now_newline.py | ||
| empty_trailing_newline.py | ||
| empty_whitespace.py | ||
| f-string-carriage-return-newline.py | ||
| form_feed.py | ||
| module_dangling_comment1.py | ||
| module_dangling_comment2.py | ||
| multiline_string_deviations.py | ||
| newlines.py | ||
| newlines.pyi | ||
| notebook_docstring.options.json | ||
| notebook_docstring.py | ||
| pattern_match_regression_brackets.py | ||
| preview.options.json | ||
| preview.py | ||
| quote_style.options.json | ||
| quote_style.py | ||
| skip_magic_trailing_comma.options.json | ||
| skip_magic_trailing_comma.py | ||
| tab_width.options.json | ||
| tab_width.py | ||
| trailing_comments.py | ||
| trivia.py | ||