mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 05:45:24 +00:00
![]() ## Summary This PR fixes the bug where the formatter would format an f-string and could potentially change the AST. For a triple-quoted f-string, the element can't be formatted into multiline if it has a format specifier because otherwise the newline would be treated as part of the format specifier. Given the following f-string: ```python f"""aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbb ccccccccccc { variable:.3f} ddddddddddddddd eeeeeeee""" ``` The formatter sees that the f-string is already multiline so it assumes that it can contain line breaks i.e., broken into multiple lines. But, in this specific case we can't format it as: ```python f"""aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbb ccccccccccc { variable:.3f } ddddddddddddddd eeeeeeee""" ``` Because the format specifier string would become ".3f\n", which is not the original string (`.3f`). If the original source code already contained a newline, they'll be preserved. For example: ```python f"""aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbb ccccccccccc { variable:.3f } ddddddddddddddd eeeeeeee""" ``` The above will be formatted as: ```py f"""aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbb ccccccccccc {variable:.3f } ddddddddddddddd eeeeeeee""" ``` Note that the newline after `.3f` is part of the format specifier which needs to be preserved. The Python version is irrelevant in this case. fixes: #10040 ## Test Plan Add some test cases to verify this behavior. |
||
---|---|---|
.. | ||
carriage_return | ||
expression | ||
fmt_on_off | ||
fmt_skip | ||
parentheses | ||
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_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_tab_indentation.options.json | ||
docstring_tab_indentation.py | ||
empty_multiple_trailing_newlines.py | ||
empty_now_newline.py | ||
empty_trailing_newline.py | ||
empty_whitespace.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 | ||
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 |