From dea65536e9581c68f5393b05647697607e5eb26e Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 1 Sep 2023 17:27:32 +0100 Subject: [PATCH] Fix placement for comments within f-strings concatenations (#7047) ## Summary Restores the dangling comment handling for f-strings, which broke with the parenthesized expression code. Closes https://github.com/astral-sh/ruff/issues/6898. ## Test Plan `cargo test` No change in any of the similarity indexes or changed file counts: | project | similarity index | total files | changed files | |--------------|------------------:|------------------:|------------------:| | cpython | 0.76083 | 1789 | 1632 | | django | 0.99957 | 2760 | 67 | | transformers | 0.99927 | 2587 | 468 | | twine | 0.99982 | 33 | 1 | | typeshed | 0.99978 | 3496 | 2173 | | warehouse | 0.99818 | 648 | 24 | | zulip | 0.99942 | 1437 | 32 | --- .../test/fixtures/ruff/expression/fstring.py | 24 ++++++++++ .../src/comments/placement.rs | 14 ++++++ .../format@expression__fstring.py.snap | 48 +++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/fstring.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/fstring.py index a60efa1cddfa8..f808f11e9421a 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/fstring.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/fstring.py @@ -33,3 +33,27 @@ # comment '' ) + +( + f'{1}' # comment + f'{2}' +) + +( + f'{1}' + f'{2}' # comment +) + +( + 1, ( # comment + f'{2}' + ) +) + +( + ( + f'{1}' + # comment + ), + 2 +) diff --git a/crates/ruff_python_formatter/src/comments/placement.rs b/crates/ruff_python_formatter/src/comments/placement.rs index 1fb7fb7f4cbea..e1f299e531ab2 100644 --- a/crates/ruff_python_formatter/src/comments/placement.rs +++ b/crates/ruff_python_formatter/src/comments/placement.rs @@ -70,6 +70,20 @@ fn handle_parenthesized_comment<'a>( comment: DecoratedComment<'a>, locator: &Locator, ) -> CommentPlacement<'a> { + // As a special-case, ignore comments within f-strings, like: + // ```python + // ( + // f'{1}' # comment + // f'{2}' + // ) + // ``` + // These can't be parenthesized, as they must fall between two string tokens in an implicit + // concatenation. But the expression ranges only include the `1` and `2` above, so we also + // can't lex the contents between them. + if comment.enclosing_node().is_expr_f_string() { + return CommentPlacement::Default(comment); + } + let Some(preceding) = comment.preceding_node() else { return CommentPlacement::Default(comment); }; diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__fstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__fstring.py.snap index aa3f0a5133aae..37fa5a5e40d98 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__fstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__fstring.py.snap @@ -39,6 +39,30 @@ result_f = ( # comment '' ) + +( + f'{1}' # comment + f'{2}' +) + +( + f'{1}' + f'{2}' # comment +) + +( + 1, ( # comment + f'{2}' + ) +) + +( + ( + f'{1}' + # comment + ), + 2 +) ``` ## Output @@ -76,6 +100,30 @@ result_f = ( # comment "" ) + +( + f"{1}" # comment + f"{2}" +) + +( + f"{1}" f"{2}" # comment +) + +( + 1, + ( # comment + f"{2}" + ), +) + +( + ( + f"{1}" + # comment + ), + 2, +) ```