Skip to content

Commit 0c2949b

Browse files
committed
Use any_over_body
1 parent bf40a37 commit 0c2949b

File tree

3 files changed

+38
-19
lines changed

3 files changed

+38
-19
lines changed

crates/ruff_linter/resources/test/fixtures/pylint/modified_iterating_set.py

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
for color in colors:
2121
colors.remove("red")
2222

23+
odds = {1, 3, 5}
24+
for num in odds:
25+
if num > 1:
26+
odds.add(num + 1)
27+
2328
# OK
2429

2530
nums = {1, 2, 3}

crates/ruff_linter/src/rules/pylint/rules/modified_iterating_set.rs

+9-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
22
use ruff_macros::{derive_message_formats, violation};
3-
use ruff_python_ast::{self as ast, Expr, Stmt, StmtFor};
3+
use ruff_python_ast::helpers::any_over_body;
4+
use ruff_python_ast::{self as ast, Expr, StmtFor};
45
use ruff_python_semantic::analyze::typing::is_set;
56
use ruff_text_size::Ranged;
67

@@ -69,19 +70,8 @@ pub(crate) fn modified_iterating_set(checker: &mut Checker, for_stmt: &StmtFor)
6970
return;
7071
}
7172

72-
if for_stmt.body.iter().any(|stmt| {
73-
// name_of_set.modify_method()
74-
// ^---------^ ^-----------^
75-
// value attr
76-
// ^-----------------------^
77-
// func
78-
// ^-------------------------^
79-
// expr, stmt
80-
let Stmt::Expr(ast::StmtExpr { value: expr, .. }) = stmt else {
81-
return false;
82-
};
83-
84-
let Some(func) = expr.as_call_expr().map(|exprcall| &exprcall.func) else {
73+
let is_modified = any_over_body(&for_stmt.body, &|expr| {
74+
let Some(func) = expr.as_call_expr().map(|call| &call.func) else {
8575
return false;
8676
};
8777

@@ -93,12 +83,14 @@ pub(crate) fn modified_iterating_set(checker: &mut Checker, for_stmt: &StmtFor)
9383
return false;
9484
};
9585

96-
let Some(binding_id_value) = checker.semantic().only_binding(value) else {
86+
let Some(value_id) = checker.semantic().only_binding(value) else {
9787
return false;
9888
};
9989

100-
binding_id == binding_id_value && modifies_set(attr.as_str())
101-
}) {
90+
binding_id == value_id && modifies_set(attr.as_str())
91+
});
92+
93+
if is_modified {
10294
let mut diagnostic = Diagnostic::new(
10395
ModifiedIteratingSet {
10496
name: name.id.clone(),

crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLE4703_modified_iterating_set.py.snap

+24-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ modified_iterating_set.py:20:1: PLE4703 [*] Iterated set `colors` is modified wi
9292
21 | | colors.remove("red")
9393
| |________________________^ PLE4703
9494
22 |
95-
23 | # OK
95+
23 | odds = {1, 3, 5}
9696
|
9797
= help: Iterate over a copy of `colors`
9898

@@ -104,4 +104,26 @@ modified_iterating_set.py:20:1: PLE4703 [*] Iterated set `colors` is modified wi
104104
20 |+for color in colors.copy():
105105
21 21 | colors.remove("red")
106106
22 22 |
107-
23 23 | # OK
107+
23 23 | odds = {1, 3, 5}
108+
109+
modified_iterating_set.py:24:1: PLE4703 [*] Iterated set `odds` is modified within the `for` loop
110+
|
111+
23 | odds = {1, 3, 5}
112+
24 | / for num in odds:
113+
25 | | if num > 1:
114+
26 | | odds.add(num + 1)
115+
| |_________________________^ PLE4703
116+
27 |
117+
28 | # OK
118+
|
119+
= help: Iterate over a copy of `odds`
120+
121+
Unsafe fix
122+
21 21 | colors.remove("red")
123+
22 22 |
124+
23 23 | odds = {1, 3, 5}
125+
24 |-for num in odds:
126+
24 |+for num in odds.copy():
127+
25 25 | if num > 1:
128+
26 26 | odds.add(num + 1)
129+
27 27 |

0 commit comments

Comments
 (0)