diff --git a/crates/ruff_linter/resources/test/fixtures/perflint/PERF401.py b/crates/ruff_linter/resources/test/fixtures/perflint/PERF401.py index aba71a26f3..21f3a34873 100644 --- a/crates/ruff_linter/resources/test/fixtures/perflint/PERF401.py +++ b/crates/ruff_linter/resources/test/fixtures/perflint/PERF401.py @@ -289,4 +289,19 @@ def f(): i = "xyz" result = [] for i in range(3): - result.append((x for x in [i])) \ No newline at end of file + 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) \ No newline at end of file diff --git a/crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs b/crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs index 66988f9292..d09e42db8d 100644 --- a/crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs +++ b/crates/ruff_linter/src/rules/perflint/rules/manual_list_comprehension.rs @@ -249,6 +249,11 @@ pub(crate) fn manual_list_comprehension(checker: &Checker, for_stmt: &ast::StmtF .iter() .find(|binding| for_stmt.target.range() == binding.range) .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, // then converting it into a comprehension would cause a NameError if target_binding diff --git a/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF401_PERF401.py.snap b/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF401_PERF401.py.snap index de479f0f02..e3ce964cde 100644 --- a/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF401_PERF401.py.snap +++ b/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__PERF401_PERF401.py.snap @@ -263,5 +263,7 @@ PERF401.py:292:9: PERF401 Use a list comprehension to create a transformed list 291 | for i in range(3): 292 | result.append((x for x in [i])) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PERF401 +293 | +294 | G_INDEX = None | = help: Replace for loop with list comprehension diff --git a/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__preview__PERF401_PERF401.py.snap b/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__preview__PERF401_PERF401.py.snap index b5ea056c83..0d0762d22e 100644 --- a/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__preview__PERF401_PERF401.py.snap +++ b/crates/ruff_linter/src/rules/perflint/snapshots/ruff_linter__rules__perflint__tests__preview__PERF401_PERF401.py.snap @@ -612,6 +612,8 @@ PERF401.py:292:9: PERF401 [*] Use a list comprehension to create a transformed l 291 | for i in range(3): 292 | result.append((x for x in [i])) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PERF401 +293 | +294 | G_INDEX = None | = 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): 292 |- result.append((x for x in [i])) 290 |+ result = [(x for x in [i]) for i in range(3)] +293 291 | +294 292 | G_INDEX = None +295 293 | def f():