From dbfdaaded12d52f4d2bfba06c94c390dad395de3 Mon Sep 17 00:00:00 2001 From: InSync Date: Fri, 17 Jan 2025 16:17:39 +0700 Subject: [PATCH] [`pylint`] Do not report methods with only one `EM101`-compatible `raise` (`PLR6301`) (#15507) --- .../test/fixtures/pylint/no_self_use.py | 37 +++++++++++++++++ .../rules/unused_arguments.rs | 2 +- .../src/rules/pylint/rules/no_self_use.rs | 2 + ...pylint__tests__PLR6301_no_self_use.py.snap | 40 +++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/no_self_use.py b/crates/ruff_linter/resources/test/fixtures/pylint/no_self_use.py index bbb966aba4..34c4709505 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/no_self_use.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/no_self_use.py @@ -103,3 +103,40 @@ class Foo: def validate_y(self, attribute, value): if value <= 0: raise ValueError("y must be a positive integer") + + +class Foo: + + # No errors + + def string(self): + msg = "" + raise NotImplementedError(msg) + + def fstring(self, x): + msg = f"{x}" + raise NotImplementedError(msg) + + def docstring(self): + """Lorem ipsum dolor sit amet.""" + msg = "" + raise NotImplementedError(msg) + + + # Errors + + def non_simple_assignment(self): + msg = foo = "" + raise NotImplementedError(msg) + + def non_simple_assignment_2(self): + msg[0] = "" + raise NotImplementedError(msg) + + def unused_message(self): + msg = "" + raise NotImplementedError("") + + def unused_message_2(self, x): + msg = "" + raise NotImplementedError(x) diff --git a/crates/ruff_linter/src/rules/flake8_unused_arguments/rules/unused_arguments.rs b/crates/ruff_linter/src/rules/flake8_unused_arguments/rules/unused_arguments.rs index 3124293a28..02ff9efbab 100644 --- a/crates/ruff_linter/src/rules/flake8_unused_arguments/rules/unused_arguments.rs +++ b/crates/ruff_linter/src/rules/flake8_unused_arguments/rules/unused_arguments.rs @@ -359,7 +359,7 @@ fn call<'a>( /// /// [`is_stub`]: function_type::is_stub /// [`EM101`]: https://docs.astral.sh/ruff/rules/raw-string-in-exception/ -fn is_not_implemented_stub_with_variable( +pub(crate) fn is_not_implemented_stub_with_variable( function_def: &StmtFunctionDef, semantic: &SemanticModel, ) -> bool { diff --git a/crates/ruff_linter/src/rules/pylint/rules/no_self_use.rs b/crates/ruff_linter/src/rules/pylint/rules/no_self_use.rs index 2e604dcd69..7cb3ba88d8 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/no_self_use.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/no_self_use.rs @@ -8,6 +8,7 @@ use ruff_python_semantic::{ }; use crate::checkers::ast::Checker; +use crate::rules::flake8_unused_arguments::rules::is_not_implemented_stub_with_variable; /// ## What it does /// Checks for the presence of unused `self` parameter in methods definitions. @@ -97,6 +98,7 @@ pub(crate) fn no_self_use( || visibility::is_overload(decorator_list, semantic) || visibility::is_property(decorator_list, extra_property_decorators, semantic) || visibility::is_validator(decorator_list, semantic) + || is_not_implemented_stub_with_variable(func, semantic) { return; } diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6301_no_self_use.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6301_no_self_use.py.snap index e53bcc34e8..124d70f358 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6301_no_self_use.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR6301_no_self_use.py.snap @@ -35,3 +35,43 @@ no_self_use.py:103:9: PLR6301 Method `validate_y` could be a function, class met 104 | if value <= 0: 105 | raise ValueError("y must be a positive integer") | + +no_self_use.py:128:9: PLR6301 Method `non_simple_assignment` could be a function, class method, or static method + | +126 | # Errors +127 | +128 | def non_simple_assignment(self): + | ^^^^^^^^^^^^^^^^^^^^^ PLR6301 +129 | msg = foo = "" +130 | raise NotImplementedError(msg) + | + +no_self_use.py:132:9: PLR6301 Method `non_simple_assignment_2` could be a function, class method, or static method + | +130 | raise NotImplementedError(msg) +131 | +132 | def non_simple_assignment_2(self): + | ^^^^^^^^^^^^^^^^^^^^^^^ PLR6301 +133 | msg[0] = "" +134 | raise NotImplementedError(msg) + | + +no_self_use.py:136:9: PLR6301 Method `unused_message` could be a function, class method, or static method + | +134 | raise NotImplementedError(msg) +135 | +136 | def unused_message(self): + | ^^^^^^^^^^^^^^ PLR6301 +137 | msg = "" +138 | raise NotImplementedError("") + | + +no_self_use.py:140:9: PLR6301 Method `unused_message_2` could be a function, class method, or static method + | +138 | raise NotImplementedError("") +139 | +140 | def unused_message_2(self, x): + | ^^^^^^^^^^^^^^^^ PLR6301 +141 | msg = "" +142 | raise NotImplementedError(x) + |