[pylint] - add unnecessary-list-index-lookup (PLR1736) + autofix#7999
[pylint] - add unnecessary-list-index-lookup (PLR1736) + autofix#7999zanieb merged 20 commits intoastral-sh:mainfrom
unnecessary-list-index-lookup (PLR1736) + autofix#7999Conversation
592f4e1 to
7cff2fb
Compare
PR Check ResultsEcosystem✅ ecosystem check detected no changes. |
d5422ed to
551ad16
Compare
unnecessary-list-index-lookup PLR1736 with autofixunnecessary-list-index-lookup (PLR1736) + autofix
5f77a1d to
f2d1f1e
Compare
|
@diceroll123 I tried out your rule and found a bug: Consider this code snippit a = list(range(5, 10))
for i, j in enumerate(a):
a[i] = j + 1
assert a[i] > jbecomes transformed to: a = list(range(5, 10))
for i, j in enumerate(a):
a[i] = j + 1
assert j > jwhich now outputs an Assertion Error. In other words, you have to make sure You should also test mutating j and changing the alias there. ie: j = j+1
assert a[i] != j |
|
@Skylion007 good catch, thanks! Will update. I think the safest and sanest way forward is to stop emitting once the visitor finds a subscript assignment to the currently-looped value. |
09b76d9 to
ee65ba8
Compare
|
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| PLR1736 | 3 | 3 | 0 | 0 | 0 |
ee65ba8 to
6a041fa
Compare
There was a problem hiding this comment.
I think @charliermarsh is better suited to review the implementation, but I read through everything as best as I could :)
The ecosystem changes look good.
| // Check that the function is the `enumerate` builtin. | ||
| let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() else { | ||
| return None; | ||
| }; | ||
| if id != "enumerate" { | ||
| return None; | ||
| }; |
There was a problem hiding this comment.
Should this use checker.semantic().resolve_call_path(func)?
There was a problem hiding this comment.
Good change, I've also added detection for builtins.enumerate along with it, thanks!
crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs
Outdated
Show resolved
Hide resolved
| def dont_fix_these(): | ||
| # once there is an assignment to the sequence[index], we stop emitting diagnostics | ||
| for index, letter in enumerate(letters): | ||
| letters[index] = "d" # Ok | ||
| assert letters[index] == "d" # Ok |
There was a problem hiding this comment.
What about a case where index is mutated? e.g. index += 1
There was a problem hiding this comment.
Adding a case for that, as well as the sequence itself being mutated! Thanks!
…ex_lookup.rs Co-authored-by: Zanie Blue <contact@zanie.dev>
…ex_lookup.rs Co-authored-by: Zanie Blue <contact@zanie.dev>
…ex_lookup.rs Co-authored-by: Zanie Blue <contact@zanie.dev>
…ex_lookup.rs Co-authored-by: Zanie Blue <contact@zanie.dev>
aed58cb to
bcae782
Compare
dhruvmanila
left a comment
There was a problem hiding this comment.
Overall this is pretty good. Thanks for the thorough test cases. I just have a few nits but those shouldn't be a blocker to merge this PR.
| @@ -0,0 +1,59 @@ | |||
| import builtins | |||
There was a problem hiding this comment.
These tests are really thorough! Thanks for thinking through them.
crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs
Outdated
Show resolved
Hide resolved
|
Will address those, all good feedback, thanks @dhruvmanila! |
Summary
Add R1736 along with the autofix
See #970
Test Plan
cargo testand manually