-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0ccca40
commit 2e496dc
Showing
8 changed files
with
118 additions
and
0 deletions.
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
crates/ruff_linter/resources/test/fixtures/pylint/dict_iter_missing_items.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
d = {1: 1, 2: 2} | ||
d_tuple = {(1, 2): 3, (4, 5): 6} | ||
l = [1, 2] | ||
s1 = {1, 2} | ||
s2 = {1, 2, 3} | ||
|
||
# Errors | ||
for k, v in d: | ||
pass | ||
|
||
# False positive, since the keys are all tuples this is valid | ||
for a, b in d_tuple: | ||
pass | ||
|
||
# Non errors | ||
for k, v in d.items(): | ||
pass | ||
for k in d.keys(): | ||
pass | ||
for i, v in enumerate(l): | ||
pass | ||
for i, v in s1.intersection(s2): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
crates/ruff_linter/src/rules/pylint/rules/dict_iter_missing_items.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use ruff_python_ast::{Expr, ExprTuple}; | ||
|
||
use ruff_diagnostics::{Diagnostic, Violation}; | ||
use ruff_macros::{derive_message_formats, violation}; | ||
use ruff_python_semantic::analyze::typing::is_dict; | ||
use ruff_text_size::Ranged; | ||
|
||
use crate::checkers::ast::Checker; | ||
|
||
/// ## What it does | ||
/// Checks for unpacking a dictionary in a for loop without calling `.items()`. | ||
/// | ||
/// ## Why is this bad? | ||
/// You are likely looking for an iteration over key, value pairs which can only be achieved | ||
/// when calling `.items()`. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// data = {"Paris": 2_165_423, "New York City": 8_804_190, "Tokyo": 13_988_129} | ||
/// for city, population in data: | ||
/// print(f"{city} has population {population}.") | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// data = {"Paris": 2_165_423, "New York City": 8_804_190, "Tokyo": 13_988_129} | ||
/// for city, population in data.items(): | ||
/// print(f"{city} has population {population}.") | ||
/// ``` | ||
#[violation] | ||
pub struct DictIterMissingItems; | ||
|
||
impl Violation for DictIterMissingItems { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Call `items()` when unpacking a dictionary for iteration") | ||
} | ||
} | ||
|
||
pub(crate) fn dict_iter_missing_items(checker: &mut Checker, target: &Expr, iter: &Expr) { | ||
let Expr::Tuple(ExprTuple { elts, .. }) = target else { | ||
return; | ||
}; | ||
|
||
if elts.len() != 2 { | ||
return; | ||
}; | ||
|
||
let Some(name) = iter.as_name_expr() else { | ||
return; | ||
}; | ||
|
||
let Some(binding) = checker | ||
.semantic() | ||
.only_binding(name) | ||
.map(|id| checker.semantic().binding(id)) | ||
else { | ||
return; | ||
}; | ||
if !is_dict(binding, checker.semantic()) { | ||
return; | ||
} | ||
|
||
checker | ||
.diagnostics | ||
.push(Diagnostic::new(DictIterMissingItems, iter.range())); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
...lint/snapshots/ruff_linter__rules__pylint__tests__PLE1141_dict_iter_missing_items.py.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
--- | ||
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 | ||
| | ||
|
||
dict_iter_missing_items.py:12: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 | ||
| | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.