mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:25:17 +00:00
F841: support fixing unused assignments in tuples by renaming variables (#9107)
## Summary
A fairly common pattern which triggers F841 is unused variables from
tuple assignments, e.g.:
user, created = User.objects.get_or_create(...)
^ F841: Local variable `created` is assigned to but never used
This error is currently not auto-fixable.
This PR adds support for fixing the error automatically by renaming the
unused variable to have a leading underscore (i.e. `_created`) **iff**
the `dummy-variable-rgx` setting would match it.
I considered using `renamers::Renamer` here, but because by the nature
of the error there should be no references to it, that seemed like
overkill. Also note that the fix might break by shadowing the new name
if it is already used elsewhere in the scope. I left it as is because
1. the renamed variable matches the "unused" regex, so it should
hopefully not already be used,
2. the fix is marked as unsafe so it should be reviewed manually
anyways, and
3. I'm not actually sure how to check the scope for the new variable
name 😅
This commit is contained in:
parent
b972455ac7
commit
c306f85691
5 changed files with 128 additions and 12 deletions
|
@ -247,6 +247,14 @@ fn remove_unused_variable(binding: &Binding, checker: &Checker) -> Option<Fix> {
|
||||||
Some(Fix::unsafe_edit(edit).isolate(isolation))
|
Some(Fix::unsafe_edit(edit).isolate(isolation))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let name = binding.name(checker.locator());
|
||||||
|
let renamed = format!("_{name}");
|
||||||
|
if checker.settings.dummy_variable_rgx.is_match(&renamed) {
|
||||||
|
let edit = Edit::range_replacement(renamed, binding.range());
|
||||||
|
|
||||||
|
return Some(Fix::unsafe_edit(edit).isolate(isolation));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ F841_0.py:20:5: F841 [*] Local variable `foo` is assigned to but never used
|
||||||
22 21 |
|
22 21 |
|
||||||
23 22 | bar = (1, 2)
|
23 22 | bar = (1, 2)
|
||||||
|
|
||||||
F841_0.py:21:6: F841 Local variable `a` is assigned to but never used
|
F841_0.py:21:6: F841 [*] Local variable `a` is assigned to but never used
|
||||||
|
|
|
|
||||||
19 | def f():
|
19 | def f():
|
||||||
20 | foo = (1, 2)
|
20 | foo = (1, 2)
|
||||||
|
@ -68,7 +68,17 @@ F841_0.py:21:6: F841 Local variable `a` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `a`
|
= help: Remove assignment to unused variable `a`
|
||||||
|
|
||||||
F841_0.py:21:9: F841 Local variable `b` is assigned to but never used
|
ℹ Unsafe fix
|
||||||
|
18 18 |
|
||||||
|
19 19 | def f():
|
||||||
|
20 20 | foo = (1, 2)
|
||||||
|
21 |- (a, b) = (1, 2)
|
||||||
|
21 |+ (_a, b) = (1, 2)
|
||||||
|
22 22 |
|
||||||
|
23 23 | bar = (1, 2)
|
||||||
|
24 24 | (c, d) = bar
|
||||||
|
|
||||||
|
F841_0.py:21:9: F841 [*] Local variable `b` is assigned to but never used
|
||||||
|
|
|
|
||||||
19 | def f():
|
19 | def f():
|
||||||
20 | foo = (1, 2)
|
20 | foo = (1, 2)
|
||||||
|
@ -79,6 +89,16 @@ F841_0.py:21:9: F841 Local variable `b` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `b`
|
= help: Remove assignment to unused variable `b`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
18 18 |
|
||||||
|
19 19 | def f():
|
||||||
|
20 20 | foo = (1, 2)
|
||||||
|
21 |- (a, b) = (1, 2)
|
||||||
|
21 |+ (a, _b) = (1, 2)
|
||||||
|
22 22 |
|
||||||
|
23 23 | bar = (1, 2)
|
||||||
|
24 24 | (c, d) = bar
|
||||||
|
|
||||||
F841_0.py:26:14: F841 [*] Local variable `baz` is assigned to but never used
|
F841_0.py:26:14: F841 [*] Local variable `baz` is assigned to but never used
|
||||||
|
|
|
|
||||||
24 | (c, d) = bar
|
24 | (c, d) = bar
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
||||||
---
|
---
|
||||||
F841_1.py:6:5: F841 Local variable `x` is assigned to but never used
|
F841_1.py:6:5: F841 [*] Local variable `x` is assigned to but never used
|
||||||
|
|
|
|
||||||
5 | def f():
|
5 | def f():
|
||||||
6 | x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
6 | x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
||||||
|
@ -9,7 +9,17 @@ F841_1.py:6:5: F841 Local variable `x` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `x`
|
= help: Remove assignment to unused variable `x`
|
||||||
|
|
||||||
F841_1.py:6:8: F841 Local variable `y` is assigned to but never used
|
ℹ Unsafe fix
|
||||||
|
3 3 |
|
||||||
|
4 4 |
|
||||||
|
5 5 | def f():
|
||||||
|
6 |- x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
||||||
|
6 |+ _x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
||||||
|
7 7 |
|
||||||
|
8 8 |
|
||||||
|
9 9 | def f():
|
||||||
|
|
||||||
|
F841_1.py:6:8: F841 [*] Local variable `y` is assigned to but never used
|
||||||
|
|
|
|
||||||
5 | def f():
|
5 | def f():
|
||||||
6 | x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
6 | x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
||||||
|
@ -17,6 +27,16 @@ F841_1.py:6:8: F841 Local variable `y` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `y`
|
= help: Remove assignment to unused variable `y`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
3 3 |
|
||||||
|
4 4 |
|
||||||
|
5 5 | def f():
|
||||||
|
6 |- x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
||||||
|
6 |+ x, _y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
||||||
|
7 7 |
|
||||||
|
8 8 |
|
||||||
|
9 9 | def f():
|
||||||
|
|
||||||
F841_1.py:16:14: F841 [*] Local variable `coords` is assigned to but never used
|
F841_1.py:16:14: F841 [*] Local variable `coords` is assigned to but never used
|
||||||
|
|
|
|
||||||
15 | def f():
|
15 | def f():
|
||||||
|
@ -53,7 +73,7 @@ F841_1.py:20:5: F841 [*] Local variable `coords` is assigned to but never used
|
||||||
22 22 |
|
22 22 |
|
||||||
23 23 | def f():
|
23 23 | def f():
|
||||||
|
|
||||||
F841_1.py:24:6: F841 Local variable `a` is assigned to but never used
|
F841_1.py:24:6: F841 [*] Local variable `a` is assigned to but never used
|
||||||
|
|
|
|
||||||
23 | def f():
|
23 | def f():
|
||||||
24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
@ -61,7 +81,14 @@ F841_1.py:24:6: F841 Local variable `a` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `a`
|
= help: Remove assignment to unused variable `a`
|
||||||
|
|
||||||
F841_1.py:24:9: F841 Local variable `b` is assigned to but never used
|
ℹ Unsafe fix
|
||||||
|
21 21 |
|
||||||
|
22 22 |
|
||||||
|
23 23 | def f():
|
||||||
|
24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
24 |+ (_a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
|
||||||
|
F841_1.py:24:9: F841 [*] Local variable `b` is assigned to but never used
|
||||||
|
|
|
|
||||||
23 | def f():
|
23 | def f():
|
||||||
24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
@ -69,7 +96,14 @@ F841_1.py:24:9: F841 Local variable `b` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `b`
|
= help: Remove assignment to unused variable `b`
|
||||||
|
|
||||||
F841_1.py:24:15: F841 Local variable `x` is assigned to but never used
|
ℹ Unsafe fix
|
||||||
|
21 21 |
|
||||||
|
22 22 |
|
||||||
|
23 23 | def f():
|
||||||
|
24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
24 |+ (a, _b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
|
||||||
|
F841_1.py:24:15: F841 [*] Local variable `x` is assigned to but never used
|
||||||
|
|
|
|
||||||
23 | def f():
|
23 | def f():
|
||||||
24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
@ -77,7 +111,14 @@ F841_1.py:24:15: F841 Local variable `x` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `x`
|
= help: Remove assignment to unused variable `x`
|
||||||
|
|
||||||
F841_1.py:24:18: F841 Local variable `y` is assigned to but never used
|
ℹ Unsafe fix
|
||||||
|
21 21 |
|
||||||
|
22 22 |
|
||||||
|
23 23 | def f():
|
||||||
|
24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
24 |+ (a, b) = (_x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
|
||||||
|
F841_1.py:24:18: F841 [*] Local variable `y` is assigned to but never used
|
||||||
|
|
|
|
||||||
23 | def f():
|
23 | def f():
|
||||||
24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
24 | (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
@ -85,4 +126,11 @@ F841_1.py:24:18: F841 Local variable `y` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `y`
|
= help: Remove assignment to unused variable `y`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
21 21 |
|
||||||
|
22 22 |
|
||||||
|
23 23 | def f():
|
||||||
|
24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||||
|
24 |+ (a, b) = (x, _y) = 1, 2 # this triggers F841 on everything
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ F841_3.py:27:46: F841 [*] Local variable `z3` is assigned to but never used
|
||||||
29 29 |
|
29 29 |
|
||||||
30 30 |
|
30 30 |
|
||||||
|
|
||||||
F841_3.py:32:6: F841 Local variable `x1` is assigned to but never used
|
F841_3.py:32:6: F841 [*] Local variable `x1` is assigned to but never used
|
||||||
|
|
|
|
||||||
31 | def f():
|
31 | def f():
|
||||||
32 | (x1, y1) = (1, 2)
|
32 | (x1, y1) = (1, 2)
|
||||||
|
@ -166,7 +166,17 @@ F841_3.py:32:6: F841 Local variable `x1` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `x1`
|
= help: Remove assignment to unused variable `x1`
|
||||||
|
|
||||||
F841_3.py:32:10: F841 Local variable `y1` is assigned to but never used
|
ℹ Unsafe fix
|
||||||
|
29 29 |
|
||||||
|
30 30 |
|
||||||
|
31 31 | def f():
|
||||||
|
32 |- (x1, y1) = (1, 2)
|
||||||
|
32 |+ (_x1, y1) = (1, 2)
|
||||||
|
33 33 | (x2, y2) = coords2 = (1, 2)
|
||||||
|
34 34 | coords3 = (x3, y3) = (1, 2)
|
||||||
|
35 35 |
|
||||||
|
|
||||||
|
F841_3.py:32:10: F841 [*] Local variable `y1` is assigned to but never used
|
||||||
|
|
|
|
||||||
31 | def f():
|
31 | def f():
|
||||||
32 | (x1, y1) = (1, 2)
|
32 | (x1, y1) = (1, 2)
|
||||||
|
@ -176,6 +186,16 @@ F841_3.py:32:10: F841 Local variable `y1` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `y1`
|
= help: Remove assignment to unused variable `y1`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
29 29 |
|
||||||
|
30 30 |
|
||||||
|
31 31 | def f():
|
||||||
|
32 |- (x1, y1) = (1, 2)
|
||||||
|
32 |+ (x1, _y1) = (1, 2)
|
||||||
|
33 33 | (x2, y2) = coords2 = (1, 2)
|
||||||
|
34 34 | coords3 = (x3, y3) = (1, 2)
|
||||||
|
35 35 |
|
||||||
|
|
||||||
F841_3.py:33:16: F841 [*] Local variable `coords2` is assigned to but never used
|
F841_3.py:33:16: F841 [*] Local variable `coords2` is assigned to but never used
|
||||||
|
|
|
|
||||||
31 | def f():
|
31 | def f():
|
||||||
|
|
|
@ -20,7 +20,7 @@ F841_4.py:12:5: F841 [*] Local variable `a` is assigned to but never used
|
||||||
14 14 |
|
14 14 |
|
||||||
15 15 |
|
15 15 |
|
||||||
|
|
||||||
F841_4.py:13:5: F841 Local variable `b` is assigned to but never used
|
F841_4.py:13:5: F841 [*] Local variable `b` is assigned to but never used
|
||||||
|
|
|
|
||||||
11 | def bar():
|
11 | def bar():
|
||||||
12 | a = foo()
|
12 | a = foo()
|
||||||
|
@ -29,7 +29,17 @@ F841_4.py:13:5: F841 Local variable `b` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `b`
|
= help: Remove assignment to unused variable `b`
|
||||||
|
|
||||||
F841_4.py:13:8: F841 Local variable `c` is assigned to but never used
|
ℹ Unsafe fix
|
||||||
|
10 10 |
|
||||||
|
11 11 | def bar():
|
||||||
|
12 12 | a = foo()
|
||||||
|
13 |- b, c = foo()
|
||||||
|
13 |+ _b, c = foo()
|
||||||
|
14 14 |
|
||||||
|
15 15 |
|
||||||
|
16 16 | def baz():
|
||||||
|
|
||||||
|
F841_4.py:13:8: F841 [*] Local variable `c` is assigned to but never used
|
||||||
|
|
|
|
||||||
11 | def bar():
|
11 | def bar():
|
||||||
12 | a = foo()
|
12 | a = foo()
|
||||||
|
@ -38,4 +48,14 @@ F841_4.py:13:8: F841 Local variable `c` is assigned to but never used
|
||||||
|
|
|
|
||||||
= help: Remove assignment to unused variable `c`
|
= help: Remove assignment to unused variable `c`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
10 10 |
|
||||||
|
11 11 | def bar():
|
||||||
|
12 12 | a = foo()
|
||||||
|
13 |- b, c = foo()
|
||||||
|
13 |+ b, _c = foo()
|
||||||
|
14 14 |
|
||||||
|
15 15 |
|
||||||
|
16 16 | def baz():
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue