Skip to content

Commit

Permalink
Don't warn PLE1141 on dicts with 2 length tuples
Browse files Browse the repository at this point in the history
See original issue at:
pylint-dev/pylint#3283
  • Loading branch information
DanielNoord committed Feb 6, 2024
1 parent 16e8e2a commit 698c2e4
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
from typing import Any


d = {1: 1, 2: 2}
d_tuple = {(1, 2): 3, (4, 5): 6}
d_tuple_annotated: Any = {(1, 2): 3, (4, 5): 6}
d_tuple_incorrect_tuple = {(1,): 3, (4, 5): 6}
l = [1, 2]
s1 = {1, 2}
s2 = {1, 2, 3}
Expand All @@ -8,10 +13,10 @@
for k, v in d:
pass

# False positive, since the keys are all tuples this is valid
for a, b in d_tuple:
for k, v in d_tuple_incorrect_tuple:
pass


# Non errors
for k, v in d.items():
pass
Expand All @@ -21,3 +26,7 @@
pass
for i, v in s1.intersection(s2):
pass
for a, b in d_tuple:
pass
for a, b in d_tuple_annotated:
pass
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@ pub(crate) fn dict_iter_missing_items(checker: &mut Checker, target: &Expr, iter
return;
}

// If we can reliably determine that a dictionary has keys that are tuples of two we don't warn
if let Some(statement) = binding.statement(checker.semantic()) {
if let Some(assignment) = statement.as_assign_stmt() {
if let Some(dict_expr) = assignment.value.as_dict_expr() {
if dict_expr.keys.iter().all(|elt| {
elt.as_ref().is_some_and(|x| {
if let Some(tuple) = x.as_tuple_expr() {
return tuple.elts.len() == 2;
}
false
})
}) {
return;
}
}
}
};

let mut diagnostic = Diagnostic::new(DictIterMissingItems, iter.range());
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
format!("{}.items()", name.id),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
---
source: crates/ruff_linter/src/rules/pylint/mod.rs
---
dict_iter_missing_items.py:8:13: PLE1141 [*] Call `items()` when unpacking a dictionary for iteration
|
7 | # Errors
8 | for k, v in d:
| ^ PLE1141
9 | pass
|
= help: Add a call to `.items()`
dict_iter_missing_items.py:13:13: PLE1141 [*] Call `items()` when unpacking a dictionary for iteration
|
12 | # Errors
13 | for k, v in d:
| ^ PLE1141
14 | pass
|
= help: Add a call to `.items()`

Safe fix
5 5 | s2 = {1, 2, 3}
6 6 |
7 7 | # Errors
8 |-for k, v in d:
8 |+for k, v in d.items():
9 9 | pass
10 10 |
11 11 | # False positive, since the keys are all tuples this is valid
10 10 | s2 = {1, 2, 3}
11 11 |
12 12 | # Errors
13 |-for k, v in d:
13 |+for k, v in d.items():
14 14 | pass
15 15 |
16 16 | for k, v in d_tuple_incorrect_tuple:

dict_iter_missing_items.py:12:13: PLE1141 [*] Call `items()` when unpacking a dictionary for iteration
dict_iter_missing_items.py:16:13: PLE1141 [*] Call `items()` when unpacking a dictionary for iteration
|
11 | # False positive, since the keys are all tuples this is valid
12 | for a, b in d_tuple:
| ^^^^^^^ PLE1141
13 | pass
14 | pass
15 |
16 | for k, v in d_tuple_incorrect_tuple:
| ^^^^^^^^^^^^^^^^^^^^^^^ PLE1141
17 | pass
|
= help: Add a call to `.items()`

Safe fix
9 9 | pass
10 10 |
11 11 | # False positive, since the keys are all tuples this is valid
12 |-for a, b in d_tuple:
12 |+for a, b in d_tuple.items():
13 13 | pass
14 14 |
15 15 | # Non errors
13 13 | for k, v in d:
14 14 | pass
15 15 |
16 |-for k, v in d_tuple_incorrect_tuple:
16 |+for k, v in d_tuple_incorrect_tuple.items():
17 17 | pass
18 18 |
19 19 |


0 comments on commit 698c2e4

Please sign in to comment.