mirror of https://github.com/astral-sh/ruff
Avoid refactoring `x[:1]`-like slices in RUF015 (#6150)
## Summary Right now, `RUF015` will try to rewrite `x[:1]` as `[next(x)]`. This isn't equivalent if `x`, for example, is empty, where slicing like `x[:1]` is forgiving, but `next` raises `StopIteration`. For me this is a little too much of a deviation to be comfortable with, and most of the value in this rule is the `x[0]` to `next(x)` conversion anyway. Closes https://github.com/astral-sh/ruff/issues/6148.
This commit is contained in:
parent
cd4147423c
commit
134d447d4c
|
|
@ -2,21 +2,9 @@ x = range(10)
|
||||||
|
|
||||||
# RUF015
|
# RUF015
|
||||||
list(x)[0]
|
list(x)[0]
|
||||||
list(x)[:1]
|
|
||||||
list(x)[:1:1]
|
|
||||||
list(x)[:1:2]
|
|
||||||
tuple(x)[0]
|
tuple(x)[0]
|
||||||
tuple(x)[:1]
|
|
||||||
tuple(x)[:1:1]
|
|
||||||
tuple(x)[:1:2]
|
|
||||||
list(i for i in x)[0]
|
list(i for i in x)[0]
|
||||||
list(i for i in x)[:1]
|
|
||||||
list(i for i in x)[:1:1]
|
|
||||||
list(i for i in x)[:1:2]
|
|
||||||
[i for i in x][0]
|
[i for i in x][0]
|
||||||
[i for i in x][:1]
|
|
||||||
[i for i in x][:1:1]
|
|
||||||
[i for i in x][:1:2]
|
|
||||||
|
|
||||||
# OK (not indexing (solely) the first element)
|
# OK (not indexing (solely) the first element)
|
||||||
list(x)
|
list(x)
|
||||||
|
|
@ -29,6 +17,9 @@ list(x)[::]
|
||||||
[i for i in x]
|
[i for i in x]
|
||||||
[i for i in x][1]
|
[i for i in x][1]
|
||||||
[i for i in x][-1]
|
[i for i in x][-1]
|
||||||
|
[i for i in x][:1]
|
||||||
|
[i for i in x][:1:1]
|
||||||
|
[i for i in x][:1:2]
|
||||||
[i for i in x][1:]
|
[i for i in x][1:]
|
||||||
[i for i in x][:3:2]
|
[i for i in x][:3:2]
|
||||||
[i for i in x][::2]
|
[i for i in x][::2]
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
use num_traits::Zero;
|
||||||
use num_traits::{One, Zero};
|
|
||||||
use ruff_python_ast::{self as ast, Comprehension, Constant, Expr, Ranged};
|
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
use ruff_python_ast::{self as ast, Comprehension, Constant, Expr, Ranged};
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::registry::AsRule;
|
use crate::registry::AsRule;
|
||||||
|
|
@ -49,37 +48,20 @@ use crate::registry::AsRule;
|
||||||
#[violation]
|
#[violation]
|
||||||
pub(crate) struct UnnecessaryIterableAllocationForFirstElement {
|
pub(crate) struct UnnecessaryIterableAllocationForFirstElement {
|
||||||
iterable: String,
|
iterable: String,
|
||||||
subscript_kind: HeadSubscriptKind,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AlwaysAutofixableViolation for UnnecessaryIterableAllocationForFirstElement {
|
impl AlwaysAutofixableViolation for UnnecessaryIterableAllocationForFirstElement {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
let UnnecessaryIterableAllocationForFirstElement {
|
let UnnecessaryIterableAllocationForFirstElement { iterable } = self;
|
||||||
iterable,
|
|
||||||
subscript_kind,
|
|
||||||
} = self;
|
|
||||||
let iterable = Self::truncate(iterable);
|
let iterable = Self::truncate(iterable);
|
||||||
match subscript_kind {
|
format!("Prefer `next({iterable})` over single element slice")
|
||||||
HeadSubscriptKind::Index => {
|
|
||||||
format!("Prefer `next({iterable})` over single element slice")
|
|
||||||
}
|
|
||||||
HeadSubscriptKind::Slice => {
|
|
||||||
format!("Prefer `[next({iterable})]` over single element slice")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
fn autofix_title(&self) -> String {
|
||||||
let UnnecessaryIterableAllocationForFirstElement {
|
let UnnecessaryIterableAllocationForFirstElement { iterable } = self;
|
||||||
iterable,
|
|
||||||
subscript_kind,
|
|
||||||
} = self;
|
|
||||||
let iterable = Self::truncate(iterable);
|
let iterable = Self::truncate(iterable);
|
||||||
match subscript_kind {
|
format!("Replace with `next({iterable})`")
|
||||||
HeadSubscriptKind::Index => format!("Replace with `next({iterable})`"),
|
|
||||||
HeadSubscriptKind::Slice => format!("Replace with `[next({iterable})]"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,9 +88,9 @@ pub(crate) fn unnecessary_iterable_allocation_for_first_element(
|
||||||
..
|
..
|
||||||
} = subscript;
|
} = subscript;
|
||||||
|
|
||||||
let Some(subscript_kind) = classify_subscript(slice) else {
|
if !is_head_slice(slice) {
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
let Some(target) = match_iteration_target(value, checker.semantic()) else {
|
let Some(target) = match_iteration_target(value, checker.semantic()) else {
|
||||||
return;
|
return;
|
||||||
|
|
@ -123,72 +105,31 @@ pub(crate) fn unnecessary_iterable_allocation_for_first_element(
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
UnnecessaryIterableAllocationForFirstElement {
|
UnnecessaryIterableAllocationForFirstElement {
|
||||||
iterable: iterable.to_string(),
|
iterable: iterable.to_string(),
|
||||||
subscript_kind,
|
|
||||||
},
|
},
|
||||||
*range,
|
*range,
|
||||||
);
|
);
|
||||||
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let replacement = match subscript_kind {
|
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||||
HeadSubscriptKind::Index => format!("next({iterable})"),
|
format!("next({iterable})"),
|
||||||
HeadSubscriptKind::Slice => format!("[next({iterable})]"),
|
*range,
|
||||||
};
|
)));
|
||||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(replacement, *range)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A subscript slice that represents the first element of a list.
|
/// Check that the slice [`Expr`] is a slice of the first element (e.g., `x[0]`).
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
fn is_head_slice(expr: &Expr) -> bool {
|
||||||
enum HeadSubscriptKind {
|
if let Expr::Constant(ast::ExprConstant {
|
||||||
/// The subscript is an index (e.g., `[0]`).
|
value: Constant::Int(value),
|
||||||
Index,
|
..
|
||||||
/// The subscript is a slice (e.g., `[:1]`).
|
}) = expr
|
||||||
Slice,
|
{
|
||||||
}
|
value.is_zero()
|
||||||
|
} else {
|
||||||
/// Check that the slice [`Expr`] is functionally equivalent to slicing into the first element. The
|
false
|
||||||
/// first `bool` checks that the element is in fact first, the second checks if it's a slice or an
|
}
|
||||||
/// index.
|
|
||||||
fn classify_subscript(expr: &Expr) -> Option<HeadSubscriptKind> {
|
|
||||||
let result = match expr {
|
|
||||||
Expr::Constant(ast::ExprConstant {
|
|
||||||
value: Constant::Int(value),
|
|
||||||
..
|
|
||||||
}) if value.is_zero() => HeadSubscriptKind::Index,
|
|
||||||
Expr::Slice(ast::ExprSlice {
|
|
||||||
step, lower, upper, ..
|
|
||||||
}) => {
|
|
||||||
// Avoid, e.g., `list(...)[:2]`
|
|
||||||
let upper = upper.as_ref()?;
|
|
||||||
let upper = as_int(upper)?;
|
|
||||||
if !upper.is_one() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid, e.g., `list(...)[2:]`.
|
|
||||||
if let Some(lower) = lower.as_ref() {
|
|
||||||
let lower = as_int(lower)?;
|
|
||||||
if !lower.is_zero() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid, e.g., `list(...)[::-1]`
|
|
||||||
if let Some(step) = step.as_ref() {
|
|
||||||
let step = as_int(step)?;
|
|
||||||
if step < upper {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HeadSubscriptKind::Slice
|
|
||||||
}
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -310,17 +251,3 @@ fn match_simple_comprehension(elt: &Expr, generators: &[Comprehension]) -> Optio
|
||||||
|
|
||||||
Some(generator.iter.range())
|
Some(generator.iter.range())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If an expression is a constant integer, returns the value of that integer; otherwise,
|
|
||||||
/// returns `None`.
|
|
||||||
fn as_int(expr: &Expr) -> Option<&BigInt> {
|
|
||||||
if let Expr::Constant(ast::ExprConstant {
|
|
||||||
value: Constant::Int(value),
|
|
||||||
..
|
|
||||||
}) = expr
|
|
||||||
{
|
|
||||||
Some(value)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ RUF015.py:4:1: RUF015 [*] Prefer `next(iter(x))` over single element slice
|
||||||
3 | # RUF015
|
3 | # RUF015
|
||||||
4 | list(x)[0]
|
4 | list(x)[0]
|
||||||
| ^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^ RUF015
|
||||||
5 | list(x)[:1]
|
5 | tuple(x)[0]
|
||||||
6 | list(x)[:1:1]
|
6 | list(i for i in x)[0]
|
||||||
|
|
|
|
||||||
= help: Replace with `next(iter(x))`
|
= help: Replace with `next(iter(x))`
|
||||||
|
|
||||||
|
|
@ -17,490 +17,238 @@ RUF015.py:4:1: RUF015 [*] Prefer `next(iter(x))` over single element slice
|
||||||
3 3 | # RUF015
|
3 3 | # RUF015
|
||||||
4 |-list(x)[0]
|
4 |-list(x)[0]
|
||||||
4 |+next(iter(x))
|
4 |+next(iter(x))
|
||||||
5 5 | list(x)[:1]
|
5 5 | tuple(x)[0]
|
||||||
6 6 | list(x)[:1:1]
|
6 6 | list(i for i in x)[0]
|
||||||
7 7 | list(x)[:1:2]
|
7 7 | [i for i in x][0]
|
||||||
|
|
||||||
RUF015.py:5:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
RUF015.py:5:1: RUF015 [*] Prefer `next(iter(x))` over single element slice
|
||||||
|
|
|
|
||||||
3 | # RUF015
|
3 | # RUF015
|
||||||
4 | list(x)[0]
|
4 | list(x)[0]
|
||||||
5 | list(x)[:1]
|
5 | tuple(x)[0]
|
||||||
| ^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^ RUF015
|
||||||
6 | list(x)[:1:1]
|
6 | list(i for i in x)[0]
|
||||||
7 | list(x)[:1:2]
|
7 | [i for i in x][0]
|
||||||
|
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
= help: Replace with `next(iter(x))`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
2 2 |
|
2 2 |
|
||||||
3 3 | # RUF015
|
3 3 | # RUF015
|
||||||
4 4 | list(x)[0]
|
4 4 | list(x)[0]
|
||||||
5 |-list(x)[:1]
|
5 |-tuple(x)[0]
|
||||||
5 |+[next(iter(x))]
|
5 |+next(iter(x))
|
||||||
6 6 | list(x)[:1:1]
|
6 6 | list(i for i in x)[0]
|
||||||
7 7 | list(x)[:1:2]
|
7 7 | [i for i in x][0]
|
||||||
8 8 | tuple(x)[0]
|
8 8 |
|
||||||
|
|
||||||
RUF015.py:6:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
RUF015.py:6:1: RUF015 [*] Prefer `next(iter(x))` over single element slice
|
||||||
|
|
|
|
||||||
4 | list(x)[0]
|
4 | list(x)[0]
|
||||||
5 | list(x)[:1]
|
5 | tuple(x)[0]
|
||||||
6 | list(x)[:1:1]
|
6 | list(i for i in x)[0]
|
||||||
| ^^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^^^^^^^^^^ RUF015
|
||||||
7 | list(x)[:1:2]
|
7 | [i for i in x][0]
|
||||||
8 | tuple(x)[0]
|
|
||||||
|
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
= help: Replace with `next(iter(x))`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
3 3 | # RUF015
|
3 3 | # RUF015
|
||||||
4 4 | list(x)[0]
|
4 4 | list(x)[0]
|
||||||
5 5 | list(x)[:1]
|
5 5 | tuple(x)[0]
|
||||||
6 |-list(x)[:1:1]
|
6 |-list(i for i in x)[0]
|
||||||
6 |+[next(iter(x))]
|
6 |+next(iter(x))
|
||||||
7 7 | list(x)[:1:2]
|
7 7 | [i for i in x][0]
|
||||||
8 8 | tuple(x)[0]
|
8 8 |
|
||||||
9 9 | tuple(x)[:1]
|
9 9 | # OK (not indexing (solely) the first element)
|
||||||
|
|
||||||
RUF015.py:7:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
RUF015.py:7:1: RUF015 [*] Prefer `next(iter(x))` over single element slice
|
||||||
|
|
|
|
||||||
5 | list(x)[:1]
|
5 | tuple(x)[0]
|
||||||
6 | list(x)[:1:1]
|
6 | list(i for i in x)[0]
|
||||||
7 | list(x)[:1:2]
|
7 | [i for i in x][0]
|
||||||
| ^^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^^^^^^ RUF015
|
||||||
8 | tuple(x)[0]
|
8 |
|
||||||
9 | tuple(x)[:1]
|
9 | # OK (not indexing (solely) the first element)
|
||||||
|
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
= help: Replace with `next(iter(x))`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
4 4 | list(x)[0]
|
4 4 | list(x)[0]
|
||||||
5 5 | list(x)[:1]
|
5 5 | tuple(x)[0]
|
||||||
6 6 | list(x)[:1:1]
|
6 6 | list(i for i in x)[0]
|
||||||
7 |-list(x)[:1:2]
|
7 |-[i for i in x][0]
|
||||||
7 |+[next(iter(x))]
|
7 |+next(iter(x))
|
||||||
8 8 | tuple(x)[0]
|
8 8 |
|
||||||
9 9 | tuple(x)[:1]
|
9 9 | # OK (not indexing (solely) the first element)
|
||||||
10 10 | tuple(x)[:1:1]
|
10 10 | list(x)
|
||||||
|
|
||||||
RUF015.py:8:1: RUF015 [*] Prefer `next(iter(x))` over single element slice
|
RUF015.py:29:1: RUF015 [*] Prefer `next(i + 1 for i in x)` over single element slice
|
||||||
|
|
|
|
||||||
6 | list(x)[:1:1]
|
28 | # RUF015 (doesn't mirror the underlying list)
|
||||||
7 | list(x)[:1:2]
|
29 | [i + 1 for i in x][0]
|
||||||
8 | tuple(x)[0]
|
|
||||||
| ^^^^^^^^^^^ RUF015
|
|
||||||
9 | tuple(x)[:1]
|
|
||||||
10 | tuple(x)[:1:1]
|
|
||||||
|
|
|
||||||
= help: Replace with `next(iter(x))`
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
5 5 | list(x)[:1]
|
|
||||||
6 6 | list(x)[:1:1]
|
|
||||||
7 7 | list(x)[:1:2]
|
|
||||||
8 |-tuple(x)[0]
|
|
||||||
8 |+next(iter(x))
|
|
||||||
9 9 | tuple(x)[:1]
|
|
||||||
10 10 | tuple(x)[:1:1]
|
|
||||||
11 11 | tuple(x)[:1:2]
|
|
||||||
|
|
||||||
RUF015.py:9:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
7 | list(x)[:1:2]
|
|
||||||
8 | tuple(x)[0]
|
|
||||||
9 | tuple(x)[:1]
|
|
||||||
| ^^^^^^^^^^^^ RUF015
|
|
||||||
10 | tuple(x)[:1:1]
|
|
||||||
11 | tuple(x)[:1:2]
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
6 6 | list(x)[:1:1]
|
|
||||||
7 7 | list(x)[:1:2]
|
|
||||||
8 8 | tuple(x)[0]
|
|
||||||
9 |-tuple(x)[:1]
|
|
||||||
9 |+[next(iter(x))]
|
|
||||||
10 10 | tuple(x)[:1:1]
|
|
||||||
11 11 | tuple(x)[:1:2]
|
|
||||||
12 12 | list(i for i in x)[0]
|
|
||||||
|
|
||||||
RUF015.py:10:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
8 | tuple(x)[0]
|
|
||||||
9 | tuple(x)[:1]
|
|
||||||
10 | tuple(x)[:1:1]
|
|
||||||
| ^^^^^^^^^^^^^^ RUF015
|
|
||||||
11 | tuple(x)[:1:2]
|
|
||||||
12 | list(i for i in x)[0]
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
7 7 | list(x)[:1:2]
|
|
||||||
8 8 | tuple(x)[0]
|
|
||||||
9 9 | tuple(x)[:1]
|
|
||||||
10 |-tuple(x)[:1:1]
|
|
||||||
10 |+[next(iter(x))]
|
|
||||||
11 11 | tuple(x)[:1:2]
|
|
||||||
12 12 | list(i for i in x)[0]
|
|
||||||
13 13 | list(i for i in x)[:1]
|
|
||||||
|
|
||||||
RUF015.py:11:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
9 | tuple(x)[:1]
|
|
||||||
10 | tuple(x)[:1:1]
|
|
||||||
11 | tuple(x)[:1:2]
|
|
||||||
| ^^^^^^^^^^^^^^ RUF015
|
|
||||||
12 | list(i for i in x)[0]
|
|
||||||
13 | list(i for i in x)[:1]
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
8 8 | tuple(x)[0]
|
|
||||||
9 9 | tuple(x)[:1]
|
|
||||||
10 10 | tuple(x)[:1:1]
|
|
||||||
11 |-tuple(x)[:1:2]
|
|
||||||
11 |+[next(iter(x))]
|
|
||||||
12 12 | list(i for i in x)[0]
|
|
||||||
13 13 | list(i for i in x)[:1]
|
|
||||||
14 14 | list(i for i in x)[:1:1]
|
|
||||||
|
|
||||||
RUF015.py:12:1: RUF015 [*] Prefer `next(iter(x))` over single element slice
|
|
||||||
|
|
|
||||||
10 | tuple(x)[:1:1]
|
|
||||||
11 | tuple(x)[:1:2]
|
|
||||||
12 | list(i for i in x)[0]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^^^^^^^^^^ RUF015
|
||||||
13 | list(i for i in x)[:1]
|
30 | [i for i in x if i > 5][0]
|
||||||
14 | list(i for i in x)[:1:1]
|
31 | [(i, i + 1) for i in x][0]
|
||||||
|
|
|
||||||
= help: Replace with `next(iter(x))`
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
9 9 | tuple(x)[:1]
|
|
||||||
10 10 | tuple(x)[:1:1]
|
|
||||||
11 11 | tuple(x)[:1:2]
|
|
||||||
12 |-list(i for i in x)[0]
|
|
||||||
12 |+next(iter(x))
|
|
||||||
13 13 | list(i for i in x)[:1]
|
|
||||||
14 14 | list(i for i in x)[:1:1]
|
|
||||||
15 15 | list(i for i in x)[:1:2]
|
|
||||||
|
|
||||||
RUF015.py:13:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
11 | tuple(x)[:1:2]
|
|
||||||
12 | list(i for i in x)[0]
|
|
||||||
13 | list(i for i in x)[:1]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
|
||||||
14 | list(i for i in x)[:1:1]
|
|
||||||
15 | list(i for i in x)[:1:2]
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
10 10 | tuple(x)[:1:1]
|
|
||||||
11 11 | tuple(x)[:1:2]
|
|
||||||
12 12 | list(i for i in x)[0]
|
|
||||||
13 |-list(i for i in x)[:1]
|
|
||||||
13 |+[next(iter(x))]
|
|
||||||
14 14 | list(i for i in x)[:1:1]
|
|
||||||
15 15 | list(i for i in x)[:1:2]
|
|
||||||
16 16 | [i for i in x][0]
|
|
||||||
|
|
||||||
RUF015.py:14:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
12 | list(i for i in x)[0]
|
|
||||||
13 | list(i for i in x)[:1]
|
|
||||||
14 | list(i for i in x)[:1:1]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
|
||||||
15 | list(i for i in x)[:1:2]
|
|
||||||
16 | [i for i in x][0]
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
11 11 | tuple(x)[:1:2]
|
|
||||||
12 12 | list(i for i in x)[0]
|
|
||||||
13 13 | list(i for i in x)[:1]
|
|
||||||
14 |-list(i for i in x)[:1:1]
|
|
||||||
14 |+[next(iter(x))]
|
|
||||||
15 15 | list(i for i in x)[:1:2]
|
|
||||||
16 16 | [i for i in x][0]
|
|
||||||
17 17 | [i for i in x][:1]
|
|
||||||
|
|
||||||
RUF015.py:15:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
13 | list(i for i in x)[:1]
|
|
||||||
14 | list(i for i in x)[:1:1]
|
|
||||||
15 | list(i for i in x)[:1:2]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
|
||||||
16 | [i for i in x][0]
|
|
||||||
17 | [i for i in x][:1]
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
12 12 | list(i for i in x)[0]
|
|
||||||
13 13 | list(i for i in x)[:1]
|
|
||||||
14 14 | list(i for i in x)[:1:1]
|
|
||||||
15 |-list(i for i in x)[:1:2]
|
|
||||||
15 |+[next(iter(x))]
|
|
||||||
16 16 | [i for i in x][0]
|
|
||||||
17 17 | [i for i in x][:1]
|
|
||||||
18 18 | [i for i in x][:1:1]
|
|
||||||
|
|
||||||
RUF015.py:16:1: RUF015 [*] Prefer `next(iter(x))` over single element slice
|
|
||||||
|
|
|
||||||
14 | list(i for i in x)[:1:1]
|
|
||||||
15 | list(i for i in x)[:1:2]
|
|
||||||
16 | [i for i in x][0]
|
|
||||||
| ^^^^^^^^^^^^^^^^^ RUF015
|
|
||||||
17 | [i for i in x][:1]
|
|
||||||
18 | [i for i in x][:1:1]
|
|
||||||
|
|
|
||||||
= help: Replace with `next(iter(x))`
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
13 13 | list(i for i in x)[:1]
|
|
||||||
14 14 | list(i for i in x)[:1:1]
|
|
||||||
15 15 | list(i for i in x)[:1:2]
|
|
||||||
16 |-[i for i in x][0]
|
|
||||||
16 |+next(iter(x))
|
|
||||||
17 17 | [i for i in x][:1]
|
|
||||||
18 18 | [i for i in x][:1:1]
|
|
||||||
19 19 | [i for i in x][:1:2]
|
|
||||||
|
|
||||||
RUF015.py:17:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
15 | list(i for i in x)[:1:2]
|
|
||||||
16 | [i for i in x][0]
|
|
||||||
17 | [i for i in x][:1]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^ RUF015
|
|
||||||
18 | [i for i in x][:1:1]
|
|
||||||
19 | [i for i in x][:1:2]
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
14 14 | list(i for i in x)[:1:1]
|
|
||||||
15 15 | list(i for i in x)[:1:2]
|
|
||||||
16 16 | [i for i in x][0]
|
|
||||||
17 |-[i for i in x][:1]
|
|
||||||
17 |+[next(iter(x))]
|
|
||||||
18 18 | [i for i in x][:1:1]
|
|
||||||
19 19 | [i for i in x][:1:2]
|
|
||||||
20 20 |
|
|
||||||
|
|
||||||
RUF015.py:18:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
16 | [i for i in x][0]
|
|
||||||
17 | [i for i in x][:1]
|
|
||||||
18 | [i for i in x][:1:1]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ RUF015
|
|
||||||
19 | [i for i in x][:1:2]
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
15 15 | list(i for i in x)[:1:2]
|
|
||||||
16 16 | [i for i in x][0]
|
|
||||||
17 17 | [i for i in x][:1]
|
|
||||||
18 |-[i for i in x][:1:1]
|
|
||||||
18 |+[next(iter(x))]
|
|
||||||
19 19 | [i for i in x][:1:2]
|
|
||||||
20 20 |
|
|
||||||
21 21 | # OK (not indexing (solely) the first element)
|
|
||||||
|
|
||||||
RUF015.py:19:1: RUF015 [*] Prefer `[next(iter(x))]` over single element slice
|
|
||||||
|
|
|
||||||
17 | [i for i in x][:1]
|
|
||||||
18 | [i for i in x][:1:1]
|
|
||||||
19 | [i for i in x][:1:2]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ RUF015
|
|
||||||
20 |
|
|
||||||
21 | # OK (not indexing (solely) the first element)
|
|
||||||
|
|
|
||||||
= help: Replace with `[next(iter(x))]
|
|
||||||
|
|
||||||
ℹ Suggested fix
|
|
||||||
16 16 | [i for i in x][0]
|
|
||||||
17 17 | [i for i in x][:1]
|
|
||||||
18 18 | [i for i in x][:1:1]
|
|
||||||
19 |-[i for i in x][:1:2]
|
|
||||||
19 |+[next(iter(x))]
|
|
||||||
20 20 |
|
|
||||||
21 21 | # OK (not indexing (solely) the first element)
|
|
||||||
22 22 | list(x)
|
|
||||||
|
|
||||||
RUF015.py:38:1: RUF015 [*] Prefer `next(i + 1 for i in x)` over single element slice
|
|
||||||
|
|
|
||||||
37 | # RUF015 (doesn't mirror the underlying list)
|
|
||||||
38 | [i + 1 for i in x][0]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ RUF015
|
|
||||||
39 | [i for i in x if i > 5][0]
|
|
||||||
40 | [(i, i + 1) for i in x][0]
|
|
||||||
|
|
|
|
||||||
= help: Replace with `next(i + 1 for i in x)`
|
= help: Replace with `next(i + 1 for i in x)`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
35 35 | [i for i in x][::]
|
26 26 | [i for i in x][::]
|
||||||
36 36 |
|
27 27 |
|
||||||
37 37 | # RUF015 (doesn't mirror the underlying list)
|
28 28 | # RUF015 (doesn't mirror the underlying list)
|
||||||
38 |-[i + 1 for i in x][0]
|
29 |-[i + 1 for i in x][0]
|
||||||
38 |+next(i + 1 for i in x)
|
29 |+next(i + 1 for i in x)
|
||||||
39 39 | [i for i in x if i > 5][0]
|
30 30 | [i for i in x if i > 5][0]
|
||||||
40 40 | [(i, i + 1) for i in x][0]
|
31 31 | [(i, i + 1) for i in x][0]
|
||||||
41 41 |
|
32 32 |
|
||||||
|
|
||||||
RUF015.py:39:1: RUF015 [*] Prefer `next(i for i in x if i > 5)` over single element slice
|
RUF015.py:30:1: RUF015 [*] Prefer `next(i for i in x if i > 5)` over single element slice
|
||||||
|
|
|
|
||||||
37 | # RUF015 (doesn't mirror the underlying list)
|
28 | # RUF015 (doesn't mirror the underlying list)
|
||||||
38 | [i + 1 for i in x][0]
|
29 | [i + 1 for i in x][0]
|
||||||
39 | [i for i in x if i > 5][0]
|
30 | [i for i in x if i > 5][0]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
||||||
40 | [(i, i + 1) for i in x][0]
|
31 | [(i, i + 1) for i in x][0]
|
||||||
|
|
|
|
||||||
= help: Replace with `next(i for i in x if i > 5)`
|
= help: Replace with `next(i for i in x if i > 5)`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
36 36 |
|
27 27 |
|
||||||
37 37 | # RUF015 (doesn't mirror the underlying list)
|
28 28 | # RUF015 (doesn't mirror the underlying list)
|
||||||
38 38 | [i + 1 for i in x][0]
|
29 29 | [i + 1 for i in x][0]
|
||||||
39 |-[i for i in x if i > 5][0]
|
30 |-[i for i in x if i > 5][0]
|
||||||
39 |+next(i for i in x if i > 5)
|
30 |+next(i for i in x if i > 5)
|
||||||
40 40 | [(i, i + 1) for i in x][0]
|
31 31 | [(i, i + 1) for i in x][0]
|
||||||
41 41 |
|
32 32 |
|
||||||
42 42 | # RUF015 (multiple generators)
|
33 33 | # RUF015 (multiple generators)
|
||||||
|
|
||||||
RUF015.py:40:1: RUF015 [*] Prefer `next((i, i + 1) for i in x)` over single element slice
|
RUF015.py:31:1: RUF015 [*] Prefer `next((i, i + 1) for i in x)` over single element slice
|
||||||
|
|
|
|
||||||
38 | [i + 1 for i in x][0]
|
29 | [i + 1 for i in x][0]
|
||||||
39 | [i for i in x if i > 5][0]
|
30 | [i for i in x if i > 5][0]
|
||||||
40 | [(i, i + 1) for i in x][0]
|
31 | [(i, i + 1) for i in x][0]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
||||||
41 |
|
32 |
|
||||||
42 | # RUF015 (multiple generators)
|
33 | # RUF015 (multiple generators)
|
||||||
|
|
|
|
||||||
= help: Replace with `next((i, i + 1) for i in x)`
|
= help: Replace with `next((i, i + 1) for i in x)`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
37 37 | # RUF015 (doesn't mirror the underlying list)
|
28 28 | # RUF015 (doesn't mirror the underlying list)
|
||||||
38 38 | [i + 1 for i in x][0]
|
29 29 | [i + 1 for i in x][0]
|
||||||
39 39 | [i for i in x if i > 5][0]
|
30 30 | [i for i in x if i > 5][0]
|
||||||
40 |-[(i, i + 1) for i in x][0]
|
31 |-[(i, i + 1) for i in x][0]
|
||||||
40 |+next((i, i + 1) for i in x)
|
31 |+next((i, i + 1) for i in x)
|
||||||
41 41 |
|
32 32 |
|
||||||
42 42 | # RUF015 (multiple generators)
|
33 33 | # RUF015 (multiple generators)
|
||||||
43 43 | y = range(10)
|
34 34 | y = range(10)
|
||||||
|
|
||||||
RUF015.py:44:1: RUF015 [*] Prefer `next(i + j for i in x for j in y)` over single element slice
|
RUF015.py:35:1: RUF015 [*] Prefer `next(i + j for i in x for j in y)` over single element slice
|
||||||
|
|
|
|
||||||
42 | # RUF015 (multiple generators)
|
33 | # RUF015 (multiple generators)
|
||||||
43 | y = range(10)
|
34 | y = range(10)
|
||||||
44 | [i + j for i in x for j in y][0]
|
35 | [i + j for i in x for j in y][0]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF015
|
||||||
45 |
|
36 |
|
||||||
46 | # RUF015
|
37 | # RUF015
|
||||||
|
|
|
|
||||||
= help: Replace with `next(i + j for i in x for j in y)`
|
= help: Replace with `next(i + j for i in x for j in y)`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
41 41 |
|
32 32 |
|
||||||
42 42 | # RUF015 (multiple generators)
|
33 33 | # RUF015 (multiple generators)
|
||||||
43 43 | y = range(10)
|
34 34 | y = range(10)
|
||||||
44 |-[i + j for i in x for j in y][0]
|
35 |-[i + j for i in x for j in y][0]
|
||||||
44 |+next(i + j for i in x for j in y)
|
35 |+next(i + j for i in x for j in y)
|
||||||
45 45 |
|
36 36 |
|
||||||
46 46 | # RUF015
|
37 37 | # RUF015
|
||||||
47 47 | list(range(10))[0]
|
38 38 | list(range(10))[0]
|
||||||
|
|
||||||
RUF015.py:47:1: RUF015 [*] Prefer `next(iter(range(10)))` over single element slice
|
RUF015.py:38:1: RUF015 [*] Prefer `next(iter(range(10)))` over single element slice
|
||||||
|
|
|
|
||||||
46 | # RUF015
|
37 | # RUF015
|
||||||
47 | list(range(10))[0]
|
38 | list(range(10))[0]
|
||||||
| ^^^^^^^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^^^^^^^ RUF015
|
||||||
48 | list(x.y)[0]
|
39 | list(x.y)[0]
|
||||||
49 | list(x["y"])[0]
|
40 | list(x["y"])[0]
|
||||||
|
|
|
|
||||||
= help: Replace with `next(iter(range(10)))`
|
= help: Replace with `next(iter(range(10)))`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
44 44 | [i + j for i in x for j in y][0]
|
35 35 | [i + j for i in x for j in y][0]
|
||||||
45 45 |
|
36 36 |
|
||||||
46 46 | # RUF015
|
37 37 | # RUF015
|
||||||
47 |-list(range(10))[0]
|
38 |-list(range(10))[0]
|
||||||
47 |+next(iter(range(10)))
|
38 |+next(iter(range(10)))
|
||||||
48 48 | list(x.y)[0]
|
39 39 | list(x.y)[0]
|
||||||
49 49 | list(x["y"])[0]
|
40 40 | list(x["y"])[0]
|
||||||
50 50 |
|
41 41 |
|
||||||
|
|
||||||
RUF015.py:48:1: RUF015 [*] Prefer `next(iter(x.y))` over single element slice
|
RUF015.py:39:1: RUF015 [*] Prefer `next(iter(x.y))` over single element slice
|
||||||
|
|
|
|
||||||
46 | # RUF015
|
37 | # RUF015
|
||||||
47 | list(range(10))[0]
|
38 | list(range(10))[0]
|
||||||
48 | list(x.y)[0]
|
39 | list(x.y)[0]
|
||||||
| ^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^ RUF015
|
||||||
49 | list(x["y"])[0]
|
40 | list(x["y"])[0]
|
||||||
|
|
|
|
||||||
= help: Replace with `next(iter(x.y))`
|
= help: Replace with `next(iter(x.y))`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
45 45 |
|
36 36 |
|
||||||
46 46 | # RUF015
|
37 37 | # RUF015
|
||||||
47 47 | list(range(10))[0]
|
38 38 | list(range(10))[0]
|
||||||
48 |-list(x.y)[0]
|
39 |-list(x.y)[0]
|
||||||
48 |+next(iter(x.y))
|
39 |+next(iter(x.y))
|
||||||
49 49 | list(x["y"])[0]
|
40 40 | list(x["y"])[0]
|
||||||
50 50 |
|
41 41 |
|
||||||
51 51 | # RUF015 (multi-line)
|
42 42 | # RUF015 (multi-line)
|
||||||
|
|
||||||
RUF015.py:49:1: RUF015 [*] Prefer `next(iter(x["y"]))` over single element slice
|
RUF015.py:40:1: RUF015 [*] Prefer `next(iter(x["y"]))` over single element slice
|
||||||
|
|
|
|
||||||
47 | list(range(10))[0]
|
38 | list(range(10))[0]
|
||||||
48 | list(x.y)[0]
|
39 | list(x.y)[0]
|
||||||
49 | list(x["y"])[0]
|
40 | list(x["y"])[0]
|
||||||
| ^^^^^^^^^^^^^^^ RUF015
|
| ^^^^^^^^^^^^^^^ RUF015
|
||||||
50 |
|
41 |
|
||||||
51 | # RUF015 (multi-line)
|
42 | # RUF015 (multi-line)
|
||||||
|
|
|
|
||||||
= help: Replace with `next(iter(x["y"]))`
|
= help: Replace with `next(iter(x["y"]))`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
46 46 | # RUF015
|
37 37 | # RUF015
|
||||||
47 47 | list(range(10))[0]
|
38 38 | list(range(10))[0]
|
||||||
48 48 | list(x.y)[0]
|
39 39 | list(x.y)[0]
|
||||||
49 |-list(x["y"])[0]
|
40 |-list(x["y"])[0]
|
||||||
49 |+next(iter(x["y"]))
|
40 |+next(iter(x["y"]))
|
||||||
50 50 |
|
41 41 |
|
||||||
51 51 | # RUF015 (multi-line)
|
42 42 | # RUF015 (multi-line)
|
||||||
52 52 | revision_heads_map_ast = [
|
43 43 | revision_heads_map_ast = [
|
||||||
|
|
||||||
RUF015.py:52:26: RUF015 [*] Prefer `next(...)` over single element slice
|
RUF015.py:43:26: RUF015 [*] Prefer `next(...)` over single element slice
|
||||||
|
|
|
|
||||||
51 | # RUF015 (multi-line)
|
42 | # RUF015 (multi-line)
|
||||||
52 | revision_heads_map_ast = [
|
43 | revision_heads_map_ast = [
|
||||||
| __________________________^
|
| __________________________^
|
||||||
53 | | a
|
44 | | a
|
||||||
54 | | for a in revision_heads_map_ast_obj.body
|
45 | | for a in revision_heads_map_ast_obj.body
|
||||||
55 | | if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP"
|
46 | | if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP"
|
||||||
56 | | ][0]
|
47 | | ][0]
|
||||||
| |____^ RUF015
|
| |____^ RUF015
|
||||||
|
|
|
|
||||||
= help: Replace with `next(...)`
|
= help: Replace with `next(...)`
|
||||||
|
|
||||||
ℹ Suggested fix
|
ℹ Suggested fix
|
||||||
49 49 | list(x["y"])[0]
|
40 40 | list(x["y"])[0]
|
||||||
50 50 |
|
41 41 |
|
||||||
51 51 | # RUF015 (multi-line)
|
42 42 | # RUF015 (multi-line)
|
||||||
52 |-revision_heads_map_ast = [
|
43 |-revision_heads_map_ast = [
|
||||||
52 |+revision_heads_map_ast = next(
|
43 |+revision_heads_map_ast = next(
|
||||||
53 53 | a
|
44 44 | a
|
||||||
54 54 | for a in revision_heads_map_ast_obj.body
|
45 45 | for a in revision_heads_map_ast_obj.body
|
||||||
55 55 | if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP"
|
46 46 | if isinstance(a, ast.Assign) and a.targets[0].id == "REVISION_HEADS_MAP"
|
||||||
56 |-][0]
|
47 |-][0]
|
||||||
56 |+)
|
47 |+)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue