Skip to content

Commit 27b19e6

Browse files
committed
Remove call when removing final argument from format
1 parent 5e9259c commit 27b19e6

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

crates/ruff_linter/resources/test/fixtures/pyflakes/F523.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@
3131
# Multiline
3232
(''
3333
.format(2))
34+
35+
# Removing the final argument.
36+
"Hello".format("world")

crates/ruff_linter/src/rules/pyflakes/fixes.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use anyhow::{Context, Ok, Result};
2-
2+
use libcst_native::Expression;
33
use ruff_diagnostics::Edit;
44
use ruff_python_ast as ast;
5+
use ruff_python_ast::Expr;
56
use ruff_python_codegen::Stylist;
67
use ruff_python_semantic::Binding;
78
use ruff_python_trivia::{BackwardsTokenizer, SimpleTokenKind, SimpleTokenizer};
@@ -69,6 +70,18 @@ pub(crate) fn remove_unused_positional_arguments_from_format_call(
6970
locator: &Locator,
7071
stylist: &Stylist,
7172
) -> Result<Edit> {
73+
// If we're removing _all_ arguments, we can remove the entire call.
74+
//
75+
// For example, `"Hello".format(", world!")` -> `"Hello"`, as opposed to `"Hello".format()`.
76+
if unused_arguments.len() == call.arguments.len() {
77+
if let Expr::Attribute(attribute) = &*call.func {
78+
return Ok(Edit::range_replacement(
79+
locator.slice(&*attribute.value).to_string(),
80+
call.range(),
81+
));
82+
}
83+
}
84+
7285
let source_code = locator.slice(call);
7386
transform_expression(source_code, stylist, |mut expression| {
7487
let call = match_call_mut(&mut expression)?;
@@ -81,7 +94,12 @@ pub(crate) fn remove_unused_positional_arguments_from_format_call(
8194
!is_unused
8295
});
8396

84-
Ok(expression)
97+
// If there are no arguments left, remove the parentheses.
98+
if call.args.is_empty() {
99+
Ok((&*call.func).clone())
100+
} else {
101+
Ok(expression)
102+
}
85103
})
86104
.map(|output| Edit::range_replacement(output, call.range()))
87105
}

crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F523_F523.py.snap

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
---
22
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
3-
snapshot_kind: text
43
---
54
F523.py:2:1: F523 [*] `.format` call has unused arguments at position(s): 1
65
|
@@ -255,12 +254,33 @@ F523.py:32:2: F523 [*] `.format` call has unused arguments at position(s): 0
255254
| __^
256255
33 | | .format(2))
257256
| |__________^ F523
257+
34 |
258+
35 | # Removing the final argument.
258259
|
259260
= help: Remove extra positional arguments at position(s): 0
260261

261262
Safe fix
263+
29 29 | "{1} {8}".format(0, 1) # F523, # F524
262264
30 30 |
263265
31 31 | # Multiline
264-
32 32 | (''
266+
32 |-(''
265267
33 |-.format(2))
266-
33 |+.format())
268+
32 |+('')
269+
34 33 |
270+
35 34 | # Removing the final argument.
271+
36 35 | "Hello".format("world")
272+
273+
F523.py:36:1: F523 [*] `.format` call has unused arguments at position(s): 0
274+
|
275+
35 | # Removing the final argument.
276+
36 | "Hello".format("world")
277+
| ^^^^^^^^^^^^^^^^^^^^^^^ F523
278+
|
279+
= help: Remove extra positional arguments at position(s): 0
280+
281+
Safe fix
282+
33 33 | .format(2))
283+
34 34 |
284+
35 35 | # Removing the final argument.
285+
36 |-"Hello".format("world")
286+
36 |+"Hello"

0 commit comments

Comments
 (0)