mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 10:22:24 +00:00
[pylint
] - restrict iteration-over-set
to only work on sets of literals (PLC0208
) (#13731)
This commit is contained in:
parent
c2dc502f3b
commit
f3612c2717
2 changed files with 25 additions and 3 deletions
|
@ -50,3 +50,13 @@ for number in {i for i in range(10)}: # set comprehensions are fine
|
|||
|
||||
for item in {*numbers_set, 4, 5, 6}: # set unpacking is fine
|
||||
print(f"I like {item}.")
|
||||
|
||||
for item in {1, 2, 3, 4, 5, 6, 2 // 1}: # operations in set literals are fine
|
||||
print(f"I like {item}.")
|
||||
|
||||
for item in {1, 2, 3, 4, 5, 6, int("7")}: # calls in set literals are fine
|
||||
print(f"I like {item}.")
|
||||
|
||||
for item in {1, 2, 2}: # duplicate literals will be ignored
|
||||
# B033 catches this
|
||||
print(f"I like {item}.")
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::Expr;
|
||||
use ruff_python_ast::{comparable::ComparableExpr, Expr};
|
||||
use ruff_text_size::Ranged;
|
||||
use rustc_hash::{FxBuildHasher, FxHashSet};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for iterations over `set` literals.
|
||||
/// Checks for iteration over a `set` literal where each element in the set is
|
||||
/// itself a literal value.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Iterating over a `set` is less efficient than iterating over a sequence
|
||||
|
@ -46,10 +48,20 @@ pub(crate) fn iteration_over_set(checker: &mut Checker, expr: &Expr) {
|
|||
return;
|
||||
};
|
||||
|
||||
if set.iter().any(Expr::is_starred_expr) {
|
||||
if set.iter().any(|value| !value.is_literal_expr()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut seen_values = FxHashSet::with_capacity_and_hasher(set.len(), FxBuildHasher);
|
||||
for value in set {
|
||||
let comparable_value = ComparableExpr::from(value);
|
||||
if !seen_values.insert(comparable_value) {
|
||||
// if the set contains a duplicate literal value, early exit.
|
||||
// rule `B033` can catch that.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(IterationOverSet, expr.range());
|
||||
|
||||
let tuple = if let [elt] = set.elts.as_slice() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue