diff --git a/crates/ruff/src/rules/ruff/rules/ambiguous_unicode_character.rs b/crates/ruff/src/rules/ruff/rules/ambiguous_unicode_character.rs index 3963e44aae..c89f132dd4 100644 --- a/crates/ruff/src/rules/ruff/rules/ambiguous_unicode_character.rs +++ b/crates/ruff/src/rules/ruff/rules/ambiguous_unicode_character.rs @@ -11,6 +11,22 @@ use crate::rules::ruff::rules::confusables::CONFUSABLES; use crate::rules::ruff::rules::Context; use crate::settings::Settings; +/// ## What it does +/// Checks for ambiguous unicode characters in strings. +/// +/// ## Why is this bad? +/// The use of ambiguous unicode characters can confuse readers and cause +/// subtle bugs. +/// +/// ## Example +/// ```python +/// print("Ηello, world!") # "Η" is the Greek eta (`U+0397`). +/// ``` +/// +/// Use instead: +/// ```python +/// print("Hello, world!") # "H" is the Latin capital H (`U+0048`). +/// ``` #[violation] pub struct AmbiguousUnicodeCharacterString { confusable: char, @@ -44,6 +60,22 @@ impl AlwaysAutofixableViolation for AmbiguousUnicodeCharacterString { } } +/// ## What it does +/// Checks for ambiguous unicode characters in docstrings. +/// +/// ## Why is this bad? +/// The use of ambiguous unicode characters can confuse readers and cause +/// subtle bugs. +/// +/// ## Example +/// ```python +/// """A lovely docstring (with a `U+FF09` parenthesis).""" +/// ``` +/// +/// Use instead: +/// ```python +/// """A lovely docstring (with no strange parentheses).""" +/// ``` #[violation] pub struct AmbiguousUnicodeCharacterDocstring { confusable: char, @@ -77,6 +109,22 @@ impl AlwaysAutofixableViolation for AmbiguousUnicodeCharacterDocstring { } } +/// ## What it does +/// Checks for ambiguous unicode characters in comments. +/// +/// ## Why is this bad? +/// The use of ambiguous unicode characters can confuse readers and cause +/// subtle bugs. +/// +/// ## Example +/// ```python +/// foo() # nоqa # "о" is Cyrillic (`U+043E`) +/// ``` +/// +/// Use instead: +/// ```python +/// foo() # noqa # "o" is Latin (`U+006F`) +/// ``` #[violation] pub struct AmbiguousUnicodeCharacterComment { confusable: char, diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index ef2da7967b..e544ab0750 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -13,6 +13,36 @@ pub struct CollectionLiteralConcatenation { expr: String, } +/// ## What it does +/// Checks for uses of the `+` operator to concatenate collections. +/// +/// ## Why is this bad? +/// In Python, the `+` operator can be used to concatenate collections (e.g., +/// `x + y` to concatenate the lists `x` and `y`). +/// +/// However, collections can be concatenated more efficiently using the +/// unpacking operator (e.g., `[*x, *y]` to concatenate `x` and `y`). +/// +/// Prefer the unpacking operator to concatenate collections, as it is more +/// readable and flexible. The `*` operator can unpack any iterable, whereas +/// `+` operates only on particular sequences which, in many cases, must be of +/// the same type. +/// +/// ## Example +/// ```python +/// foo = [2, 3, 4] +/// bar = [1] + foo + [5, 6] +/// ``` +/// +/// Use instead: +/// ```python +/// foo = [2, 3, 4] +/// bar = [1, *foo, 5, 6] +/// ``` +/// +/// ## References +/// - [PEP 448 – Additional Unpacking Generalizations](https://peps.python.org/pep-0448/) +/// - [Python docs: Sequence Types — `list`, `tuple`, `range`](https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range) impl Violation for CollectionLiteralConcatenation { const AUTOFIX: AutofixKind = AutofixKind::Sometimes; diff --git a/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs b/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs index 5aec8dc085..657a1638aa 100644 --- a/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs +++ b/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs @@ -6,6 +6,32 @@ use ruff_macros::{derive_message_formats, violation}; use crate::checkers::ast::Checker; +/// ## What it does +/// Checks for use of `zip()` to iterate over successive pairs of elements. +/// +/// ## Why is this bad? +/// When iterating over successive pairs of elements, prefer +/// `itertools.pairwise()` over `zip()`. +/// +/// `itertools.pairwise()` is more readable and conveys the intent of the code +/// more clearly. +/// +/// ## Example +/// ```python +/// letters = "ABCD" +/// zip(letters, letters[1:]) # ("A", "B"), ("B", "C"), ("C", "D") +/// ``` +/// +/// Use instead: +/// ```python +/// from itertools import pairwise +/// +/// letters = "ABCD" +/// pairwise(letters) # ("A", "B"), ("B", "C"), ("C", "D") +/// ``` +/// +/// ## References +/// - [Python documentation: `itertools.pairwise`](https://docs.python.org/3/library/itertools.html#itertools.pairwise) #[violation] pub struct PairwiseOverZipped;