diff --git a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs index e8660df0a5..c3468d88d3 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/unnecessary_iterable_allocation_for_first_element.rs @@ -11,14 +11,21 @@ use crate::checkers::ast::Checker; use crate::fix::snippet::SourceCodeSnippet; /// ## What it does -/// Checks for uses of `list(...)[0]` that can be replaced with -/// `next(iter(...))`. +/// Checks the following constructs, all of which can be replaced by +/// `next(iter(...))`: +/// +/// - `list(...)[0]` +/// - `tuple(...)[0]` +/// - `list(i for i in ...)[0]` +/// - `[i for i in ...][0]` +/// - `list(...).pop(0)` /// /// ## Why is this bad? -/// Calling `list(...)` will create a new list of the entire collection, which -/// can be very expensive for large collections. If you only need the first -/// element of the collection, you can use `next(...)` or `next(iter(...)` to -/// lazily fetch the first element. +/// Calling e.g. `list(...)` will create a new list of the entire collection, +/// which can be very expensive for large collections. If you only need the +/// first element of the collection, you can use `next(...)` or +/// `next(iter(...)` to lazily fetch the first element. The same is true for +/// the other constructs. /// /// ## Example /// ```python @@ -33,14 +40,16 @@ use crate::fix::snippet::SourceCodeSnippet; /// ``` /// /// ## Fix safety -/// This rule's fix is marked as unsafe, as migrating from `list(...)[0]` to -/// `next(iter(...))` can change the behavior of your program in two ways: +/// This rule's fix is marked as unsafe, as migrating from e.g. `list(...)[0]` +/// to `next(iter(...))` can change the behavior of your program in two ways: /// -/// 1. First, `list(...)` will eagerly evaluate the entire collection, while -/// `next(iter(...))` will only evaluate the first element. As such, any -/// side effects that occur during iteration will be delayed. -/// 2. Second, `list(...)[0]` will raise `IndexError` if the collection is -/// empty, while `next(iter(...))` will raise `StopIteration`. +/// 1. First, all above mentioned constructs will eagerly evaluate the entire +/// collection, while `next(iter(...))` will only evaluate the first +/// element. As such, any side effects that occur during iteration will be +/// delayed. +/// 2. Second, accessing members of a collection via square bracket notation +/// `[0]` of the `pop()` function will raise `IndexError` if the collection +/// is empty, while `next(iter(...))` will raise `StopIteration`. /// /// ## References /// - [Iterators and Iterables in Python: Run Efficient Iterations](https://realpython.com/python-iterators-iterables/#when-to-use-an-iterator-in-python)