mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-03 05:13:00 +00:00
[perflint] Ignore rule if target is global or nonlocal (PERF401) (#19539)
## Summary Resolves #19531 I've implemented a check to determine whether the for_stmt target is declared as global or nonlocal. I believe we should skip the rule in all such cases, since variables declared this way are intended for use outside the loop scope, making value changes expected behavior. ## Test Plan Added two test cases for global and nonlocal variable to snapshot.
This commit is contained in:
parent
4016aff057
commit
e4f64480da
4 changed files with 28 additions and 1 deletions
|
|
@ -289,4 +289,19 @@ def f():
|
||||||
i = "xyz"
|
i = "xyz"
|
||||||
result = []
|
result = []
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
result.append((x for x in [i]))
|
result.append((x for x in [i]))
|
||||||
|
|
||||||
|
G_INDEX = None
|
||||||
|
def f():
|
||||||
|
global G_INDEX
|
||||||
|
result = []
|
||||||
|
for G_INDEX in range(3):
|
||||||
|
result.append(G_INDEX)
|
||||||
|
|
||||||
|
def f():
|
||||||
|
NL_INDEX = None
|
||||||
|
def x():
|
||||||
|
nonlocal NL_INDEX
|
||||||
|
result = []
|
||||||
|
for NL_INDEX in range(3):
|
||||||
|
result.append(NL_INDEX)
|
||||||
|
|
@ -249,6 +249,11 @@ pub(crate) fn manual_list_comprehension(checker: &Checker, for_stmt: &ast::StmtF
|
||||||
.iter()
|
.iter()
|
||||||
.find(|binding| for_stmt.target.range() == binding.range)
|
.find(|binding| for_stmt.target.range() == binding.range)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
// If the target variable is global (e.g., `global INDEX`) or nonlocal (e.g., `nonlocal INDEX`),
|
||||||
|
// then it is intended to be used elsewhere outside the for loop.
|
||||||
|
if target_binding.is_global() || target_binding.is_nonlocal() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// If any references to the loop target variable are after the loop,
|
// If any references to the loop target variable are after the loop,
|
||||||
// then converting it into a comprehension would cause a NameError
|
// then converting it into a comprehension would cause a NameError
|
||||||
if target_binding
|
if target_binding
|
||||||
|
|
|
||||||
|
|
@ -263,5 +263,7 @@ PERF401.py:292:9: PERF401 Use a list comprehension to create a transformed list
|
||||||
291 | for i in range(3):
|
291 | for i in range(3):
|
||||||
292 | result.append((x for x in [i]))
|
292 | result.append((x for x in [i]))
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PERF401
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PERF401
|
||||||
|
293 |
|
||||||
|
294 | G_INDEX = None
|
||||||
|
|
|
|
||||||
= help: Replace for loop with list comprehension
|
= help: Replace for loop with list comprehension
|
||||||
|
|
|
||||||
|
|
@ -612,6 +612,8 @@ PERF401.py:292:9: PERF401 [*] Use a list comprehension to create a transformed l
|
||||||
291 | for i in range(3):
|
291 | for i in range(3):
|
||||||
292 | result.append((x for x in [i]))
|
292 | result.append((x for x in [i]))
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PERF401
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PERF401
|
||||||
|
293 |
|
||||||
|
294 | G_INDEX = None
|
||||||
|
|
|
|
||||||
= help: Replace for loop with list comprehension
|
= help: Replace for loop with list comprehension
|
||||||
|
|
||||||
|
|
@ -623,3 +625,6 @@ PERF401.py:292:9: PERF401 [*] Use a list comprehension to create a transformed l
|
||||||
291 |- for i in range(3):
|
291 |- for i in range(3):
|
||||||
292 |- result.append((x for x in [i]))
|
292 |- result.append((x for x in [i]))
|
||||||
290 |+ result = [(x for x in [i]) for i in range(3)]
|
290 |+ result = [(x for x in [i]) for i in range(3)]
|
||||||
|
293 291 |
|
||||||
|
294 292 | G_INDEX = None
|
||||||
|
295 293 | def f():
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue