Avoid converting expression to statement in invald contexts (#1239)

This commit is contained in:
Charlie Marsh
2022-12-14 13:57:25 -05:00
committed by GitHub
parent 630b4b627d
commit 0aa356c96c
5 changed files with 58 additions and 39 deletions

View File

@@ -20,6 +20,8 @@ getattr(foo, "_123abc")
getattr(foo, "abc123")
getattr(foo, r"abc123")
_ = lambda x: getattr(x, "bar")
if getattr(x, "bar"):
pass
# Valid setattr usage
setattr(foo, bar, None)
@@ -28,6 +30,8 @@ setattr(foo, "123abc", None)
setattr(foo, r"123\abc", None)
setattr(foo, "except", None)
_ = lambda x: setattr(x, "bar", 1)
if setattr(x, "bar", 1):
pass
# Invalid usage
setattr(foo, "bar", None)

View File

@@ -1557,14 +1557,7 @@ where
flake8_bugbear::plugins::getattr_with_constant(self, expr, func, args);
}
if self.settings.enabled.contains(&CheckCode::B010) {
if !self
.scope_stack
.iter()
.rev()
.any(|index| matches!(self.scopes[*index].kind, ScopeKind::Lambda(..)))
{
flake8_bugbear::plugins::setattr_with_constant(self, expr, func, args);
}
flake8_bugbear::plugins::setattr_with_constant(self, expr, func, args);
}
if self.settings.enabled.contains(&CheckCode::B022) {
flake8_bugbear::plugins::useless_contextlib_suppress(self, expr, args);

View File

@@ -56,16 +56,23 @@ pub fn setattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, ar
if KWLIST.contains(&name.as_str()) {
return;
}
let mut check = Check::new(CheckKind::SetAttrWithConstant, Range::from_located(expr));
if checker.patch(check.kind.code()) {
match assignment(obj, name, value) {
Ok(content) => check.amend(Fix::replacement(
content,
expr.location,
expr.end_location.unwrap(),
)),
Err(e) => error!("Failed to fix invalid comparison: {e}"),
};
// We can only replace a `setattr` call (which is an `Expr`) with an assignment
// (which is a `Stmt`) if the `Expr` is already being used as a `Stmt`
// (i.e., it's directly within an `StmtKind::Expr`).
if let StmtKind::Expr { value: child } = &checker.current_parent().0.node {
if expr == child.as_ref() {
let mut check = Check::new(CheckKind::SetAttrWithConstant, Range::from_located(expr));
if checker.patch(check.kind.code()) {
match assignment(obj, name, value) {
Ok(content) => check.amend(Fix::replacement(
content,
expr.location,
expr.end_location.unwrap(),
)),
Err(e) => error!("Failed to fix invalid comparison: {e}"),
};
}
checker.add_check(check);
}
}
checker.add_check(check);
}

View File

@@ -77,4 +77,19 @@ expression: checks
end_location:
row: 22
column: 31
- kind: GetAttrWithConstant
location:
row: 23
column: 3
end_location:
row: 23
column: 20
fix:
content: x.bar
location:
row: 23
column: 3
end_location:
row: 23
column: 20

View File

@@ -4,77 +4,77 @@ expression: checks
---
- kind: SetAttrWithConstant
location:
row: 33
row: 37
column: 0
end_location:
row: 33
row: 37
column: 25
fix:
content: foo.bar = None
location:
row: 33
row: 37
column: 0
end_location:
row: 33
row: 37
column: 25
- kind: SetAttrWithConstant
location:
row: 34
row: 38
column: 0
end_location:
row: 34
row: 38
column: 29
fix:
content: foo._123abc = None
location:
row: 34
row: 38
column: 0
end_location:
row: 34
row: 38
column: 29
- kind: SetAttrWithConstant
location:
row: 35
row: 39
column: 0
end_location:
row: 35
row: 39
column: 28
fix:
content: foo.abc123 = None
location:
row: 35
row: 39
column: 0
end_location:
row: 35
row: 39
column: 28
- kind: SetAttrWithConstant
location:
row: 36
row: 40
column: 0
end_location:
row: 36
row: 40
column: 29
fix:
content: foo.abc123 = None
location:
row: 36
row: 40
column: 0
end_location:
row: 36
row: 40
column: 29
- kind: SetAttrWithConstant
location:
row: 37
row: 41
column: 0
end_location:
row: 37
row: 41
column: 30
fix:
content: foo.bar.baz = None
location:
row: 37
row: 41
column: 0
end_location:
row: 37
row: 41
column: 30