diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index a3b71b2b44..aec861d287 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -206,12 +206,12 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "E0237") => (RuleGroup::Stable, rules::pylint::rules::NonSlotAssignment), (Pylint, "E0241") => (RuleGroup::Stable, rules::pylint::rules::DuplicateBases), (Pylint, "E0302") => (RuleGroup::Stable, rules::pylint::rules::UnexpectedSpecialMethodSignature), - (Pylint, "E0303") => (RuleGroup::Preview, rules::pylint::rules::InvalidLengthReturnType), + (Pylint, "E0303") => (RuleGroup::Stable, rules::pylint::rules::InvalidLengthReturnType), (Pylint, "E0304") => (RuleGroup::Preview, rules::pylint::rules::InvalidBoolReturnType), - (Pylint, "E0305") => (RuleGroup::Preview, rules::pylint::rules::InvalidIndexReturnType), + (Pylint, "E0305") => (RuleGroup::Stable, rules::pylint::rules::InvalidIndexReturnType), (Pylint, "E0307") => (RuleGroup::Stable, rules::pylint::rules::InvalidStrReturnType), - (Pylint, "E0308") => (RuleGroup::Preview, rules::pylint::rules::InvalidBytesReturnType), - (Pylint, "E0309") => (RuleGroup::Preview, rules::pylint::rules::InvalidHashReturnType), + (Pylint, "E0308") => (RuleGroup::Stable, rules::pylint::rules::InvalidBytesReturnType), + (Pylint, "E0309") => (RuleGroup::Stable, rules::pylint::rules::InvalidHashReturnType), (Pylint, "E0604") => (RuleGroup::Stable, rules::pylint::rules::InvalidAllObject), (Pylint, "E0605") => (RuleGroup::Stable, rules::pylint::rules::InvalidAllFormat), (Pylint, "E0643") => (RuleGroup::Stable, rules::pylint::rules::PotentialIndexError), @@ -225,8 +225,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "E1307") => (RuleGroup::Stable, rules::pylint::rules::BadStringFormatType), (Pylint, "E1310") => (RuleGroup::Stable, rules::pylint::rules::BadStrStripCall), (Pylint, "E1507") => (RuleGroup::Stable, rules::pylint::rules::InvalidEnvvarValue), - (Pylint, "E1519") => (RuleGroup::Preview, rules::pylint::rules::SingledispatchMethod), - (Pylint, "E1520") => (RuleGroup::Preview, rules::pylint::rules::SingledispatchmethodFunction), + (Pylint, "E1519") => (RuleGroup::Stable, rules::pylint::rules::SingledispatchMethod), + (Pylint, "E1520") => (RuleGroup::Stable, rules::pylint::rules::SingledispatchmethodFunction), (Pylint, "E1700") => (RuleGroup::Stable, rules::pylint::rules::YieldFromInAsyncFunction), (Pylint, "E2502") => (RuleGroup::Stable, rules::pylint::rules::BidirectionalUnicode), (Pylint, "E2510") => (RuleGroup::Stable, rules::pylint::rules::InvalidCharacterBackspace), @@ -256,7 +256,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "R1711") => (RuleGroup::Stable, rules::pylint::rules::UselessReturn), (Pylint, "R1714") => (RuleGroup::Stable, rules::pylint::rules::RepeatedEqualityComparison), (Pylint, "R1722") => (RuleGroup::Stable, rules::pylint::rules::SysExitAlias), - (Pylint, "R1730") => (RuleGroup::Preview, rules::pylint::rules::IfStmtMinMax), + (Pylint, "R1730") => (RuleGroup::Stable, rules::pylint::rules::IfStmtMinMax), (Pylint, "R1733") => (RuleGroup::Preview, rules::pylint::rules::UnnecessaryDictIndexLookup), (Pylint, "R1736") => (RuleGroup::Stable, rules::pylint::rules::UnnecessaryListIndexLookup), (Pylint, "R2004") => (RuleGroup::Stable, rules::pylint::rules::MagicValueComparison), @@ -273,13 +273,13 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "W0129") => (RuleGroup::Stable, rules::pylint::rules::AssertOnStringLiteral), (Pylint, "W0131") => (RuleGroup::Stable, rules::pylint::rules::NamedExprWithoutContext), (Pylint, "W0133") => (RuleGroup::Stable, rules::pylint::rules::UselessExceptionStatement), - (Pylint, "W0211") => (RuleGroup::Preview, rules::pylint::rules::BadStaticmethodArgument), + (Pylint, "W0211") => (RuleGroup::Stable, rules::pylint::rules::BadStaticmethodArgument), (Pylint, "W0245") => (RuleGroup::Stable, rules::pylint::rules::SuperWithoutBrackets), (Pylint, "W0406") => (RuleGroup::Stable, rules::pylint::rules::ImportSelf), (Pylint, "W0602") => (RuleGroup::Stable, rules::pylint::rules::GlobalVariableNotAssigned), (Pylint, "W0603") => (RuleGroup::Stable, rules::pylint::rules::GlobalStatement), (Pylint, "W0604") => (RuleGroup::Stable, rules::pylint::rules::GlobalAtModuleLevel), - (Pylint, "W0642") => (RuleGroup::Preview, rules::pylint::rules::SelfOrClsAssignment), + (Pylint, "W0642") => (RuleGroup::Stable, rules::pylint::rules::SelfOrClsAssignment), (Pylint, "W0711") => (RuleGroup::Stable, rules::pylint::rules::BinaryOpException), (Pylint, "W1501") => (RuleGroup::Stable, rules::pylint::rules::BadOpenMode), (Pylint, "W1508") => (RuleGroup::Stable, rules::pylint::rules::InvalidEnvvarDefault), diff --git a/crates/ruff_linter/src/rules/pylint/rules/if_stmt_min_max.rs b/crates/ruff_linter/src/rules/pylint/rules/if_stmt_min_max.rs index 9d31d3711b..f83280dc28 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/if_stmt_min_max.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/if_stmt_min_max.rs @@ -14,7 +14,7 @@ use crate::fix::snippet::SourceCodeSnippet; /// /// ## Why is this bad? /// An `if` statement that selects the lesser or greater of two sub-expressions -/// can be replaced with a `min()` or `max()` call respectively. When possible, +/// can be replaced with a `min()` or `max()` call respectively. Where possible, /// prefer `min()` and `max()`, as they're more concise and readable than the /// equivalent `if` statements. /// @@ -194,7 +194,7 @@ enum MinMax { } impl MinMax { - fn as_str(self) -> &'static str { + const fn as_str(self) -> &'static str { match self { Self::Min => "min", Self::Max => "max", diff --git a/crates/ruff_linter/src/rules/pylint/rules/invalid_bytes_return.rs b/crates/ruff_linter/src/rules/pylint/rules/invalid_bytes_return.rs index 846c4c86c9..8287fbb16f 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/invalid_bytes_return.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/invalid_bytes_return.rs @@ -12,7 +12,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; /// ## What it does -/// Checks for `__bytes__` implementations that return a type other than `bytes`. +/// Checks for `__bytes__` implementations that return types other than `bytes`. /// /// ## Why is this bad? /// The `__bytes__` method should return a `bytes` object. Returning a different diff --git a/crates/ruff_linter/src/rules/pylint/rules/invalid_hash_return.rs b/crates/ruff_linter/src/rules/pylint/rules/invalid_hash_return.rs index 1a32228c50..187ec300c5 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/invalid_hash_return.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/invalid_hash_return.rs @@ -12,7 +12,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; /// ## What it does -/// Checks for `__hash__` implementations that return a value other than an integer. +/// Checks for `__hash__` implementations that return non-integer values. /// /// ## Why is this bad? /// The `__hash__` method should return an integer. Returning a different @@ -20,7 +20,7 @@ use crate::checkers::ast::Checker; /// /// Note: `bool` is a subclass of `int`, so it's technically valid for `__hash__` to /// return `True` or `False`. However, for consistency with other rules, Ruff will -/// still raise when `__hash__` returns a `bool`. +/// still emit a diagnostic when `__hash__` returns a `bool`. /// /// ## Example /// ```python @@ -36,7 +36,6 @@ use crate::checkers::ast::Checker; /// return 2 /// ``` /// -/// /// ## References /// - [Python documentation: The `__hash__` method](https://docs.python.org/3/reference/datamodel.html#object.__hash__) #[violation] diff --git a/crates/ruff_linter/src/rules/pylint/rules/invalid_index_return.rs b/crates/ruff_linter/src/rules/pylint/rules/invalid_index_return.rs index d92ee4a259..eea1bafa77 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/invalid_index_return.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/invalid_index_return.rs @@ -12,7 +12,7 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; /// ## What it does -/// Checks for `__index__` implementations that return a value other than an integer. +/// Checks for `__index__` implementations that return non-integer values. /// /// ## Why is this bad? /// The `__index__` method should return an integer. Returning a different @@ -38,7 +38,6 @@ use crate::checkers::ast::Checker; /// return 2 /// ``` /// -/// /// ## References /// - [Python documentation: The `__index__` method](https://docs.python.org/3/reference/datamodel.html#object.__index__) #[violation] diff --git a/crates/ruff_linter/src/rules/pylint/rules/invalid_length_return.rs b/crates/ruff_linter/src/rules/pylint/rules/invalid_length_return.rs index e36984c24a..6b8b21f477 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/invalid_length_return.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/invalid_length_return.rs @@ -12,8 +12,8 @@ use ruff_text_size::Ranged; use crate::checkers::ast::Checker; /// ## What it does -/// Checks for `__len__` implementations that return values other than a non-negative -/// integer. +/// Checks for `__len__` implementations that return values that are not non-negative +/// integers. /// /// ## Why is this bad? /// The `__len__` method should return a non-negative integer. Returning a different @@ -21,7 +21,7 @@ use crate::checkers::ast::Checker; /// /// Note: `bool` is a subclass of `int`, so it's technically valid for `__len__` to /// return `True` or `False`. However, for consistency with other rules, Ruff will -/// still raise when `__len__` returns a `bool`. +/// still emit a diagnostic when `__len__` returns a `bool`. /// /// ## Example /// ```python @@ -37,7 +37,6 @@ use crate::checkers::ast::Checker; /// return 2 /// ``` /// -/// /// ## References /// - [Python documentation: The `__len__` method](https://docs.python.org/3/reference/datamodel.html#object.__len__) #[violation] diff --git a/crates/ruff_linter/src/rules/pylint/rules/self_or_cls_assignment.rs b/crates/ruff_linter/src/rules/pylint/rules/self_or_cls_assignment.rs index 622c1aaee9..0c5b2ff6e8 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/self_or_cls_assignment.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/self_or_cls_assignment.rs @@ -11,30 +11,36 @@ use crate::checkers::ast::Checker; /// Checks for assignment of `self` and `cls` in instance and class methods respectively. /// /// ## Why is this bad? -/// The identifiers `self` and `cls` are conventional in Python for the first argument of instance -/// methods and class methods, respectively. +/// The identifiers `self` and `cls` are conventional in Python for the first parameter of instance +/// methods and class methods, respectively. Assigning new values to these variables can be +/// confusing for others reading your code; using a different variable name can lead to clearer +/// code. /// /// ## Example /// /// ```python -/// class Versions: -/// def add(self, version): -/// self = version +/// class Version: +/// def add(self, other): +/// self = self + other +/// return self /// /// @classmethod -/// def from_list(cls, versions): -/// cls = versions +/// def superclass(cls): +/// cls = cls.__mro__[-1] +/// return cls /// ``` /// /// Use instead: /// ```python -/// class Versions: -/// def add(self, version): -/// self.versions.append(version) +/// class Version: +/// def add(self, other): +/// new_version = self + other +/// return new_version /// /// @classmethod -/// def from_list(cls, versions): -/// return cls(versions) +/// def superclass(cls): +/// supercls = cls.__mro__[-1] +/// return supercls /// ``` #[violation] pub struct SelfOrClsAssignment { @@ -47,10 +53,14 @@ impl Violation for SelfOrClsAssignment { let SelfOrClsAssignment { method_type } = self; format!( - "Invalid assignment to `{}` argument in {method_type} method", + "Confusing assignment to `{}` argument in {method_type} method", method_type.arg_name(), ) } + + fn fix_title(&self) -> Option { + Some("Consider using a different variable name".to_string()) + } } /// PLW0127 @@ -130,7 +140,7 @@ enum MethodType { } impl MethodType { - fn arg_name(self) -> &'static str { + const fn arg_name(self) -> &'static str { match self { MethodType::Instance => "self", MethodType::Class => "cls", diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0642_self_or_cls_assignment.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0642_self_or_cls_assignment.py.snap index 8cf7aa94b1..4e7e2e5376 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0642_self_or_cls_assignment.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLW0642_self_or_cls_assignment.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -self_or_cls_assignment.py:4:9: PLW0642 Invalid assignment to `cls` argument in class method +self_or_cls_assignment.py:4:9: PLW0642 Confusing assignment to `cls` argument in class method | 2 | @classmethod 3 | def list_fruits(cls) -> None: @@ -10,8 +10,9 @@ self_or_cls_assignment.py:4:9: PLW0642 Invalid assignment to `cls` argument in c 5 | cls: Fruit = "apple" # PLW0642 6 | cls += "orange" # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:5:9: PLW0642 Invalid assignment to `cls` argument in class method +self_or_cls_assignment.py:5:9: PLW0642 Confusing assignment to `cls` argument in class method | 3 | def list_fruits(cls) -> None: 4 | cls = "apple" # PLW0642 @@ -20,8 +21,9 @@ self_or_cls_assignment.py:5:9: PLW0642 Invalid assignment to `cls` argument in c 6 | cls += "orange" # PLW0642 7 | *cls = "banana" # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:6:9: PLW0642 Invalid assignment to `cls` argument in class method +self_or_cls_assignment.py:6:9: PLW0642 Confusing assignment to `cls` argument in class method | 4 | cls = "apple" # PLW0642 5 | cls: Fruit = "apple" # PLW0642 @@ -30,8 +32,9 @@ self_or_cls_assignment.py:6:9: PLW0642 Invalid assignment to `cls` argument in c 7 | *cls = "banana" # PLW0642 8 | cls, blah = "apple", "orange" # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:7:10: PLW0642 Invalid assignment to `cls` argument in class method +self_or_cls_assignment.py:7:10: PLW0642 Confusing assignment to `cls` argument in class method | 5 | cls: Fruit = "apple" # PLW0642 6 | cls += "orange" # PLW0642 @@ -40,8 +43,9 @@ self_or_cls_assignment.py:7:10: PLW0642 Invalid assignment to `cls` argument in 8 | cls, blah = "apple", "orange" # PLW0642 9 | blah, (cls, blah2) = "apple", ("orange", "banana") # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:8:9: PLW0642 Invalid assignment to `cls` argument in class method +self_or_cls_assignment.py:8:9: PLW0642 Confusing assignment to `cls` argument in class method | 6 | cls += "orange" # PLW0642 7 | *cls = "banana" # PLW0642 @@ -50,8 +54,9 @@ self_or_cls_assignment.py:8:9: PLW0642 Invalid assignment to `cls` argument in c 9 | blah, (cls, blah2) = "apple", ("orange", "banana") # PLW0642 10 | blah, [cls, blah2] = "apple", ("orange", "banana") # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:9:16: PLW0642 Invalid assignment to `cls` argument in class method +self_or_cls_assignment.py:9:16: PLW0642 Confusing assignment to `cls` argument in class method | 7 | *cls = "banana" # PLW0642 8 | cls, blah = "apple", "orange" # PLW0642 @@ -59,8 +64,9 @@ self_or_cls_assignment.py:9:16: PLW0642 Invalid assignment to `cls` argument in | ^^^ PLW0642 10 | blah, [cls, blah2] = "apple", ("orange", "banana") # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:10:16: PLW0642 Invalid assignment to `cls` argument in class method +self_or_cls_assignment.py:10:16: PLW0642 Confusing assignment to `cls` argument in class method | 8 | cls, blah = "apple", "orange" # PLW0642 9 | blah, (cls, blah2) = "apple", ("orange", "banana") # PLW0642 @@ -69,8 +75,9 @@ self_or_cls_assignment.py:10:16: PLW0642 Invalid assignment to `cls` argument in 11 | 12 | @classmethod | + = help: Consider using a different variable name -self_or_cls_assignment.py:14:9: PLW0642 Invalid assignment to `cls` argument in class method +self_or_cls_assignment.py:14:9: PLW0642 Confusing assignment to `cls` argument in class method | 12 | @classmethod 13 | def add_fruits(cls, fruits, /) -> None: @@ -79,8 +86,9 @@ self_or_cls_assignment.py:14:9: PLW0642 Invalid assignment to `cls` argument in 15 | 16 | def print_color(self) -> None: | + = help: Consider using a different variable name -self_or_cls_assignment.py:17:9: PLW0642 Invalid assignment to `self` argument in instance method +self_or_cls_assignment.py:17:9: PLW0642 Confusing assignment to `self` argument in instance method | 16 | def print_color(self) -> None: 17 | self = "red" # PLW0642 @@ -88,8 +96,9 @@ self_or_cls_assignment.py:17:9: PLW0642 Invalid assignment to `self` argument in 18 | self: Self = "red" # PLW0642 19 | self += "blue" # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:18:9: PLW0642 Invalid assignment to `self` argument in instance method +self_or_cls_assignment.py:18:9: PLW0642 Confusing assignment to `self` argument in instance method | 16 | def print_color(self) -> None: 17 | self = "red" # PLW0642 @@ -98,8 +107,9 @@ self_or_cls_assignment.py:18:9: PLW0642 Invalid assignment to `self` argument in 19 | self += "blue" # PLW0642 20 | *self = "blue" # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:19:9: PLW0642 Invalid assignment to `self` argument in instance method +self_or_cls_assignment.py:19:9: PLW0642 Confusing assignment to `self` argument in instance method | 17 | self = "red" # PLW0642 18 | self: Self = "red" # PLW0642 @@ -108,8 +118,9 @@ self_or_cls_assignment.py:19:9: PLW0642 Invalid assignment to `self` argument in 20 | *self = "blue" # PLW0642 21 | self, blah = "red", "blue" # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:20:10: PLW0642 Invalid assignment to `self` argument in instance method +self_or_cls_assignment.py:20:10: PLW0642 Confusing assignment to `self` argument in instance method | 18 | self: Self = "red" # PLW0642 19 | self += "blue" # PLW0642 @@ -118,8 +129,9 @@ self_or_cls_assignment.py:20:10: PLW0642 Invalid assignment to `self` argument i 21 | self, blah = "red", "blue" # PLW0642 22 | blah, (self, blah2) = "apple", ("orange", "banana") # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:21:9: PLW0642 Invalid assignment to `self` argument in instance method +self_or_cls_assignment.py:21:9: PLW0642 Confusing assignment to `self` argument in instance method | 19 | self += "blue" # PLW0642 20 | *self = "blue" # PLW0642 @@ -128,8 +140,9 @@ self_or_cls_assignment.py:21:9: PLW0642 Invalid assignment to `self` argument in 22 | blah, (self, blah2) = "apple", ("orange", "banana") # PLW0642 23 | blah, [self, blah2] = "apple", ("orange", "banana") # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:22:16: PLW0642 Invalid assignment to `self` argument in instance method +self_or_cls_assignment.py:22:16: PLW0642 Confusing assignment to `self` argument in instance method | 20 | *self = "blue" # PLW0642 21 | self, blah = "red", "blue" # PLW0642 @@ -137,8 +150,9 @@ self_or_cls_assignment.py:22:16: PLW0642 Invalid assignment to `self` argument i | ^^^^ PLW0642 23 | blah, [self, blah2] = "apple", ("orange", "banana") # PLW0642 | + = help: Consider using a different variable name -self_or_cls_assignment.py:23:16: PLW0642 Invalid assignment to `self` argument in instance method +self_or_cls_assignment.py:23:16: PLW0642 Confusing assignment to `self` argument in instance method | 21 | self, blah = "red", "blue" # PLW0642 22 | blah, (self, blah2) = "apple", ("orange", "banana") # PLW0642 @@ -147,8 +161,9 @@ self_or_cls_assignment.py:23:16: PLW0642 Invalid assignment to `self` argument i 24 | 25 | def print_color(self, color, /) -> None: | + = help: Consider using a different variable name -self_or_cls_assignment.py:26:9: PLW0642 Invalid assignment to `self` argument in instance method +self_or_cls_assignment.py:26:9: PLW0642 Confusing assignment to `self` argument in instance method | 25 | def print_color(self, color, /) -> None: 26 | self = color @@ -156,3 +171,4 @@ self_or_cls_assignment.py:26:9: PLW0642 Invalid assignment to `self` argument in 27 | 28 | def ok(self) -> None: | + = help: Consider using a different variable name