Make B007 fix relevance stricter (#4607)

This commit is contained in:
Charlie Marsh
2023-05-23 11:43:59 -04:00
committed by GitHub
parent 652c644c2a
commit f3bdd2e7be
3 changed files with 44 additions and 37 deletions

View File

@@ -73,7 +73,18 @@ def f():
def f():
# Fixable.
# Unfixable.
for foo, bar, baz in (["1", "2", "3"],):
if foo or baz:
break
else:
bar = 1
print(bar)
def f():
# Unfixable (false negative) due to usage of `bar` outside of loop.
for foo, bar, baz in (["1", "2", "3"],):
if foo or baz:
break
@@ -85,4 +96,4 @@ def f():
# Unfixable due to trailing underscore (`_line_` wouldn't be considered an ignorable
# variable name).
for line_ in range(self.header_lines):
fp.readline()
fp.readline()

View File

@@ -152,24 +152,19 @@ pub(crate) fn unused_loop_control_variable(checker: &mut Checker, target: &Expr,
);
if let Some(rename) = rename {
if certainty.into() && checker.patch(diagnostic.kind.rule()) {
// Find the `BindingKind::LoopVar` corresponding to the name.
// Avoid fixing if the variable, or any future bindings to the variable, are
// used _after_ the loop.
let scope = checker.semantic_model().scope();
let binding = scope.bindings_for_name(name).find_map(|binding_id| {
let binding = &checker.semantic_model().bindings[*binding_id];
binding.source.and_then(|source| {
(Some(source) == checker.semantic_model().stmt_id).then_some(binding)
})
});
if let Some(binding) = binding {
if binding.kind.is_loop_var() {
if !binding.used() {
#[allow(deprecated)]
diagnostic.set_fix(Fix::unspecified(Edit::range_replacement(
rename,
expr.range(),
)));
}
}
if scope
.bindings_for_name(name)
.map(|binding_id| &checker.semantic_model().bindings[*binding_id])
.all(|binding| !binding.used())
{
#[allow(deprecated)]
diagnostic.set_fix(Fix::unspecified(Edit::range_replacement(
rename,
expr.range(),
)));
}
}
}

View File

@@ -152,10 +152,10 @@ B007.py:68:14: B007 [*] Loop control variable `bar` not used within loop body
70 70 | break
71 71 |
B007.py:77:14: B007 [*] Loop control variable `bar` not used within loop body
B007.py:77:14: B007 Loop control variable `bar` not used within loop body
|
77 | def f():
78 | # Fixable.
78 | # Unfixable.
79 | for foo, bar, baz in (["1", "2", "3"],):
| ^^^ B007
80 | if foo or baz:
@@ -163,23 +163,24 @@ B007.py:77:14: B007 [*] Loop control variable `bar` not used within loop body
|
= help: Rename unused `bar` to `_bar`
Suggested fix
74 74 |
75 75 | def f():
76 76 | # Fixable.
77 |- for foo, bar, baz in (["1", "2", "3"],):
77 |+ for foo, _bar, baz in (["1", "2", "3"],):
78 78 | if foo or baz:
79 79 | break
80 80 |
B007.py:87:5: B007 Loop control variable `line_` not used within loop body
B007.py:88:14: B007 Loop control variable `bar` not used within loop body
|
87 | # Unfixable due to trailing underscore (`_line_` wouldn't be considered an ignorable
88 | # variable name).
89 | for line_ in range(self.header_lines):
| ^^^^^ B007
90 | fp.readline()
88 | def f():
89 | # Unfixable (false negative) due to usage of `bar` outside of loop.
90 | for foo, bar, baz in (["1", "2", "3"],):
| ^^^ B007
91 | if foo or baz:
92 | break
|
= help: Rename unused `bar` to `_bar`
B007.py:98:5: B007 Loop control variable `line_` not used within loop body
|
98 | # Unfixable due to trailing underscore (`_line_` wouldn't be considered an ignorable
99 | # variable name).
100 | for line_ in range(self.header_lines):
| ^^^^^ B007
101 | fp.readline()
|