mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:15:12 +00:00
Fix formatting of comments between function and arguments (#6826)
## Summary We now format comments between a function and its arguments as dangling. Like with other strange placements, I've biased towards preserving the existing formatting, rather than attempting to reorder the comments. Closes https://github.com/astral-sh/ruff/issues/6818. ## Test Plan `cargo test` Before: | project | similarity index | |--------------|------------------| | cpython | 0.76050 | | django | 0.99820 | | transformers | 0.99800 | | twine | 0.99876 | | typeshed | 0.99953 | | warehouse | 0.99615 | | zulip | 0.99729 | After: | project | similarity index | |--------------|------------------| | cpython | 0.76050 | | django | 0.99820 | | transformers | 0.99800 | | twine | 0.99876 | | typeshed | 0.99953 | | warehouse | 0.99615 | | zulip | 0.99729 |
This commit is contained in:
parent
f754ad5898
commit
59e70896c0
6 changed files with 186 additions and 32 deletions
|
@ -1,10 +1,10 @@
|
|||
use crate::expression::CallChainLayout;
|
||||
|
||||
use ruff_formatter::{format_args, write, FormatRuleWithOptions};
|
||||
use ruff_formatter::FormatRuleWithOptions;
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use ruff_python_ast::{Expr, ExprCall};
|
||||
|
||||
use crate::comments::{dangling_comments, SourceComment};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::expression::CallChainLayout;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
|
@ -30,13 +30,25 @@ impl FormatNodeRule<ExprCall> for FormatExprCall {
|
|||
arguments,
|
||||
} = item;
|
||||
|
||||
let comments = f.context().comments().clone();
|
||||
let dangling = comments.dangling(item);
|
||||
|
||||
let call_chain_layout = self.call_chain_layout.apply_in_node(item, f);
|
||||
|
||||
let fmt_func = format_with(|f| match func.as_ref() {
|
||||
Expr::Attribute(expr) => expr.format().with_options(call_chain_layout).fmt(f),
|
||||
Expr::Call(expr) => expr.format().with_options(call_chain_layout).fmt(f),
|
||||
Expr::Subscript(expr) => expr.format().with_options(call_chain_layout).fmt(f),
|
||||
_ => func.format().fmt(f),
|
||||
let fmt_func = format_with(|f| {
|
||||
// Format the function expression.
|
||||
match func.as_ref() {
|
||||
Expr::Attribute(expr) => expr.format().with_options(call_chain_layout).fmt(f),
|
||||
Expr::Call(expr) => expr.format().with_options(call_chain_layout).fmt(f),
|
||||
Expr::Subscript(expr) => expr.format().with_options(call_chain_layout).fmt(f),
|
||||
_ => func.format().fmt(f),
|
||||
}?;
|
||||
|
||||
// Format comments between the function and its arguments.
|
||||
dangling_comments(dangling).fmt(f)?;
|
||||
|
||||
// Format the arguments.
|
||||
arguments.format().fmt(f)
|
||||
});
|
||||
|
||||
// Allow to indent the parentheses while
|
||||
|
@ -48,11 +60,19 @@ impl FormatNodeRule<ExprCall> for FormatExprCall {
|
|||
if call_chain_layout == CallChainLayout::Fluent
|
||||
&& self.call_chain_layout == CallChainLayout::Default
|
||||
{
|
||||
group(&format_args![fmt_func, arguments.format()]).fmt(f)
|
||||
group(&fmt_func).fmt(f)
|
||||
} else {
|
||||
write!(f, [fmt_func, arguments.format()])
|
||||
fmt_func.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_dangling_comments(
|
||||
&self,
|
||||
_dangling_comments: &[SourceComment],
|
||||
_f: &mut PyFormatter,
|
||||
) -> FormatResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl NeedsParentheses for ExprCall {
|
||||
|
@ -65,6 +85,8 @@ impl NeedsParentheses for ExprCall {
|
|||
== CallChainLayout::Fluent
|
||||
{
|
||||
OptionalParentheses::Multiline
|
||||
} else if context.comments().has_dangling(self) {
|
||||
OptionalParentheses::Always
|
||||
} else {
|
||||
self.func.needs_parentheses(self.into(), context)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue