Skip to content

Commit

Permalink
Detect enumerate iterations in loop-iterator-mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jul 17, 2024
1 parent 9a2dafb commit 88da797
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,7 @@ def __init__(self, ls):
some_list[elem] = 1
some_list.remove(elem)
some_list.discard(elem)

# should error
for i, elem in enumerate(some_list):
some_list.pop(0)
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,29 @@ pub(crate) fn loop_iterator_mutation(checker: &mut Checker, stmt_for: &StmtFor)
range: _,
} = stmt_for;

if !matches!(iter.as_ref(), Expr::Name(_) | Expr::Attribute(_)) {
return;
}
let (target, iter) = match iter.as_ref() {
Expr::Name(_) | Expr::Attribute(_) => {
// Ex) `for item in items:`
(&**target, &**iter)
}
Expr::Call(ExprCall {
func, arguments, ..
}) => {
// Ex) `for i, item in enumerate(items):`
if checker.semantic().match_builtin_expr(func, "enumerate") {
if let [iter] = &*arguments.args {
(&**target, iter)
} else {
return;
}
} else {
return;
}
}
_ => {
return;
}
};

// Collect mutations to the iterable.
let mutations = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,11 @@ B909.py:150:8: B909 Mutation to loop iterable `some_list` during iteration
151 | pass
152 | else:
|

B909.py:164:5: B909 Mutation to loop iterable `some_list` during iteration
|
162 | # should error
163 | for i, elem in enumerate(some_list):
164 | some_list.pop(0)
| ^^^^^^^^^^^^^ B909
|

0 comments on commit 88da797

Please sign in to comment.