diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py index f959e005a7..76a8a49950 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py @@ -25,6 +25,7 @@ with ( with ( a # a as # as + # own line b # b , # comma c # c @@ -32,6 +33,13 @@ with ( ... # body # body trailing own +with ( + a # a + as # as + # own line + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb # b +): pass + with (a,): # magic trailing comma ... diff --git a/crates/ruff_python_formatter/src/comments/placement.rs b/crates/ruff_python_formatter/src/comments/placement.rs index 7a03f67ac8..54ff3fc828 100644 --- a/crates/ruff_python_formatter/src/comments/placement.rs +++ b/crates/ruff_python_formatter/src/comments/placement.rs @@ -1370,15 +1370,15 @@ fn handle_with_item_comment<'a>( SimpleTokenKind::As, ); - // If before the `as` keyword, then it must be a trailing comment of the context expression. if comment.end() < as_token.start() { + // If before the `as` keyword, then it must be a trailing comment of the context expression. CommentPlacement::trailing(context_expr, comment) } // Trailing end of line comment coming after the `as` keyword`. else if comment.line_position().is_end_of_line() { CommentPlacement::dangling(comment.enclosing_node(), comment) } else { - CommentPlacement::Default(comment) + CommentPlacement::leading(optional_vars, comment) } } diff --git a/crates/ruff_python_formatter/src/other/with_item.rs b/crates/ruff_python_formatter/src/other/with_item.rs index 6a4034d633..960180b473 100644 --- a/crates/ruff_python_formatter/src/other/with_item.rs +++ b/crates/ruff_python_formatter/src/other/with_item.rs @@ -2,7 +2,7 @@ use rustpython_parser::ast::WithItem; use ruff_formatter::{write, Buffer, FormatResult}; -use crate::comments::trailing_comments; +use crate::comments::{leading_comments, trailing_comments}; use crate::expression::maybe_parenthesize_expression; use crate::expression::parentheses::Parenthesize; use crate::prelude::*; @@ -27,14 +27,22 @@ impl FormatNodeRule for FormatWithItem { if let Some(optional_vars) = optional_vars { write!( f, - [ - space(), - text("as"), - trailing_comments(trailing_as_comments), - space(), - optional_vars.format(), - ] + [space(), text("as"), trailing_comments(trailing_as_comments)] )?; + let leading_var_comments = comments.leading_comments(optional_vars.as_ref()); + if leading_var_comments.is_empty() { + write!(f, [space(), optional_vars.format()])?; + } else { + write!( + f, + [ + // Otherwise the comment would end up on the same line as the `as` + hard_line_break(), + leading_comments(leading_var_comments), + optional_vars.format() + ] + )?; + } } Ok(()) } diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap index 6cd292b2cc..3140929dc1 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__with.py.snap @@ -31,6 +31,7 @@ with ( with ( a # a as # as + # own line b # b , # comma c # c @@ -38,6 +39,13 @@ with ( ... # body # body trailing own +with ( + a # a + as # as + # own line + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb # b +): pass + with (a,): # magic trailing comma ... @@ -142,12 +150,21 @@ with ( with ( - a as b, # a # as # b # comma + a as # a # as + # own line + b, # b # comma c, # c ): # colon ... # body # body trailing own +with ( + a as # a # as + # own line + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb # b +): + pass + with ( a,