mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 04:45:01 +00:00
Don't reorder parameters in function calls (#7268)
## Summary In `f(*args, a=b, *args2, **kwargs)` the args (`*args`, `*args2`) and keywords (`a=b`, `**kwargs`) are interleaved, which we previously didn't handle. Fixes #6498 **main** | project | similarity index | total files | changed files | |--------------|------------------:|------------------:|------------------:| | cpython | 0.76083 | 1789 | 1632 | | **django** | 0.99966 | 2760 | 58 | | transformers | 0.99930 | 2587 | 447 | | twine | 1.00000 | 33 | 0 | | typeshed | 0.99983 | 3496 | 18 | | warehouse | 0.99825 | 648 | 22 | | zulip | 0.99950 | 1437 | 27 | **PR** | project | similarity index | total files | changed files | |--------------|------------------:|------------------:|------------------:| | cpython | 0.76083 | 1789 | 1632 | | **django** | 0.99967 | 2760 | 53 | | transformers | 0.99930 | 2587 | 447 | | twine | 1.00000 | 33 | 0 | | typeshed | 0.99983 | 3496 | 18 | | warehouse | 0.99825 | 648 | 22 | | zulip | 0.99950 | 1437 | 27 | ## Test Plan New fixtures
This commit is contained in:
parent
56440ad835
commit
f4c7bff36b
6 changed files with 203 additions and 129 deletions
|
@ -1,6 +1,5 @@
|
|||
use ruff_formatter::write;
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::{Arguments, Expr};
|
||||
use ruff_python_ast::{ArgOrKeyword, Arguments, Expr};
|
||||
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||
|
||||
|
@ -14,6 +13,11 @@ pub struct FormatArguments;
|
|||
|
||||
impl FormatNodeRule<Arguments> for FormatArguments {
|
||||
fn fmt_fields(&self, item: &Arguments, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
let Arguments {
|
||||
range,
|
||||
args,
|
||||
keywords,
|
||||
} = item;
|
||||
// We have a case with `f()` without any argument, which is a special case because we can
|
||||
// have a comment with no node attachment inside:
|
||||
// ```python
|
||||
|
@ -21,7 +25,7 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
// # This call has a dangling comment.
|
||||
// )
|
||||
// ```
|
||||
if item.args.is_empty() && item.keywords.is_empty() {
|
||||
if args.is_empty() && keywords.is_empty() {
|
||||
let comments = f.context().comments().clone();
|
||||
let dangling = comments.dangling(item);
|
||||
return write!(f, [empty_parenthesized("(", dangling, ")")]);
|
||||
|
@ -29,9 +33,9 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
|
||||
let all_arguments = format_with(|f: &mut PyFormatter| {
|
||||
let source = f.context().source();
|
||||
let mut joiner = f.join_comma_separated(item.end());
|
||||
match item.args.as_slice() {
|
||||
[arg] if item.keywords.is_empty() => {
|
||||
let mut joiner = f.join_comma_separated(range.end());
|
||||
match args.as_slice() {
|
||||
[arg] if keywords.is_empty() => {
|
||||
match arg {
|
||||
Expr::GeneratorExp(generator_exp) => joiner.entry(
|
||||
generator_exp,
|
||||
|
@ -41,7 +45,7 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
),
|
||||
other => {
|
||||
let parentheses =
|
||||
if is_single_argument_parenthesized(arg, item.end(), source) {
|
||||
if is_single_argument_parenthesized(arg, range.end(), source) {
|
||||
Parentheses::Always
|
||||
} else {
|
||||
// Note: no need to handle opening-parenthesis comments, since
|
||||
|
@ -53,14 +57,17 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
}
|
||||
};
|
||||
}
|
||||
args => {
|
||||
joiner
|
||||
.entries(
|
||||
// We have the parentheses from the call so the item never need any
|
||||
args.iter()
|
||||
.map(|arg| (arg, arg.format().with_options(Parentheses::Preserve))),
|
||||
)
|
||||
.nodes(item.keywords.iter());
|
||||
_ => {
|
||||
for arg_or_keyword in item.arguments_source_order() {
|
||||
match arg_or_keyword {
|
||||
ArgOrKeyword::Arg(arg) => {
|
||||
joiner.entry(arg, &arg.format());
|
||||
}
|
||||
ArgOrKeyword::Keyword(keyword) => {
|
||||
joiner.entry(keyword, &keyword.format());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +83,7 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
// c,
|
||||
// )
|
||||
let comments = f.context().comments().clone();
|
||||
let dangling_comments = comments.dangling(item.as_any_node_ref());
|
||||
let dangling_comments = comments.dangling(item);
|
||||
|
||||
write!(
|
||||
f,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue