mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +00:00
Implement autofix for unnecessary-lambda
(PLW0108
) (#8621)
Closes https://github.com/astral-sh/ruff/issues/8618.
This commit is contained in:
parent
d7144d6d8e
commit
9724dfd939
2 changed files with 122 additions and 13 deletions
|
@ -1,5 +1,6 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::helpers::contains_effect;
|
||||
use ruff_python_ast::visitor::Visitor;
|
||||
use ruff_python_ast::{self as ast, visitor, Expr, ExprLambda, Parameter, ParameterWithDefault};
|
||||
use ruff_text_size::Ranged;
|
||||
|
@ -24,14 +25,29 @@ use crate::checkers::ast::Checker;
|
|||
/// ```python
|
||||
/// df.apply(str)
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// This rule's fix is marked as unsafe in cases in which the lambda body itself
|
||||
/// contains an effect.
|
||||
///
|
||||
/// For example, replacing `lambda x, y: (func()(x, y))` with `func()` would
|
||||
/// lead to a change in behavior, as `func()` would be evaluated eagerly when
|
||||
/// defining the lambda, rather than when the lambda is called.
|
||||
///
|
||||
/// When the lambda body contains no visible effects, the fix is considered
|
||||
/// safe.
|
||||
#[violation]
|
||||
pub struct UnnecessaryLambda;
|
||||
|
||||
impl Violation for UnnecessaryLambda {
|
||||
impl AlwaysFixableViolation for UnnecessaryLambda {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Lambda may be unnecessary; consider inlining inner function")
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> String {
|
||||
"Inline function call".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// PLW0108
|
||||
|
@ -184,9 +200,19 @@ pub(crate) fn unnecessary_lambda(checker: &mut Checker, lambda: &ExprLambda) {
|
|||
}
|
||||
}
|
||||
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(UnnecessaryLambda, lambda.range()));
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryLambda, lambda.range());
|
||||
diagnostic.set_fix(Fix::applicable_edit(
|
||||
Edit::range_replacement(
|
||||
checker.locator().slice(func.as_ref()).to_string(),
|
||||
lambda.range(),
|
||||
),
|
||||
if contains_effect(func.as_ref(), |id| checker.semantic().is_builtin(id)) {
|
||||
Applicability::Unsafe
|
||||
} else {
|
||||
Applicability::Safe
|
||||
},
|
||||
));
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
/// Identify all `Expr::Name` nodes in an AST.
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
unnecessary_lambda.py:1:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
||||
unnecessary_lambda.py:1:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
||||
|
|
||||
1 | _ = lambda: print() # [unnecessary-lambda]
|
||||
| ^^^^^^^^^^^^^^^ PLW0108
|
||||
2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
|
|
||||
= help: Inline function call
|
||||
|
||||
unnecessary_lambda.py:2:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
||||
ℹ Safe fix
|
||||
1 |-_ = lambda: print() # [unnecessary-lambda]
|
||||
1 |+_ = print # [unnecessary-lambda]
|
||||
2 2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
3 3 |
|
||||
4 4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
|
||||
unnecessary_lambda.py:2:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
||||
|
|
||||
1 | _ = lambda: print() # [unnecessary-lambda]
|
||||
2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
|
@ -16,8 +24,17 @@ unnecessary_lambda.py:2:5: PLW0108 Lambda may be unnecessary; consider inlining
|
|||
3 |
|
||||
4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
|
|
||||
= help: Inline function call
|
||||
|
||||
unnecessary_lambda.py:4:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
||||
ℹ Safe fix
|
||||
1 1 | _ = lambda: print() # [unnecessary-lambda]
|
||||
2 |-_ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
2 |+_ = min # [unnecessary-lambda]
|
||||
3 3 |
|
||||
4 4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
5 5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
|
||||
unnecessary_lambda.py:4:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
||||
|
|
||||
2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
3 |
|
||||
|
@ -26,8 +43,19 @@ unnecessary_lambda.py:4:5: PLW0108 Lambda may be unnecessary; consider inlining
|
|||
5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda]
|
||||
|
|
||||
= help: Inline function call
|
||||
|
||||
unnecessary_lambda.py:5:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
||||
ℹ Safe fix
|
||||
1 1 | _ = lambda: print() # [unnecessary-lambda]
|
||||
2 2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
3 3 |
|
||||
4 |-_ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
4 |+_ = f # [unnecessary-lambda]
|
||||
5 5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
6 6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda]
|
||||
7 7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
|
||||
unnecessary_lambda.py:5:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
||||
|
|
||||
4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
|
@ -35,8 +63,19 @@ unnecessary_lambda.py:5:5: PLW0108 Lambda may be unnecessary; consider inlining
|
|||
6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda]
|
||||
7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
|
|
||||
= help: Inline function call
|
||||
|
||||
unnecessary_lambda.py:6:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
||||
ℹ Safe fix
|
||||
2 2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
3 3 |
|
||||
4 4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
5 |-_ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
5 |+_ = f # [unnecessary-lambda]
|
||||
6 6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda]
|
||||
7 7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
8 8 |
|
||||
|
||||
unnecessary_lambda.py:6:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
||||
|
|
||||
4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
|
@ -44,8 +83,19 @@ unnecessary_lambda.py:6:5: PLW0108 Lambda may be unnecessary; consider inlining
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108
|
||||
7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
|
|
||||
= help: Inline function call
|
||||
|
||||
unnecessary_lambda.py:7:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
||||
ℹ Safe fix
|
||||
3 3 |
|
||||
4 4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
5 5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
6 |-_ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda]
|
||||
6 |+_ = f # [unnecessary-lambda]
|
||||
7 7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
8 8 |
|
||||
9 9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda]
|
||||
|
||||
unnecessary_lambda.py:7:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
||||
|
|
||||
5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda]
|
||||
|
@ -54,8 +104,19 @@ unnecessary_lambda.py:7:5: PLW0108 Lambda may be unnecessary; consider inlining
|
|||
8 |
|
||||
9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda]
|
||||
|
|
||||
= help: Inline function call
|
||||
|
||||
unnecessary_lambda.py:9:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
||||
ℹ Safe fix
|
||||
4 4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
5 5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
6 6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda]
|
||||
7 |-_ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
7 |+_ = f # [unnecessary-lambda]
|
||||
8 8 |
|
||||
9 9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda]
|
||||
10 10 | _ = lambda x, y: f(lambda x, y: x + y)(x, y) # [unnecessary-lambda]
|
||||
|
||||
unnecessary_lambda.py:9:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
||||
|
|
||||
7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
8 |
|
||||
|
@ -63,8 +124,19 @@ unnecessary_lambda.py:9:5: PLW0108 Lambda may be unnecessary; consider inlining
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108
|
||||
10 | _ = lambda x, y: f(lambda x, y: x + y)(x, y) # [unnecessary-lambda]
|
||||
|
|
||||
= help: Inline function call
|
||||
|
||||
unnecessary_lambda.py:10:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
||||
ℹ Unsafe fix
|
||||
6 6 | _ = lambda *args, **kwargs: f(*args, **kwargs) # [unnecessary-lambda]
|
||||
7 7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
8 8 |
|
||||
9 |-_ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda]
|
||||
9 |+_ = f(lambda x: x) # [unnecessary-lambda]
|
||||
10 10 | _ = lambda x, y: f(lambda x, y: x + y)(x, y) # [unnecessary-lambda]
|
||||
11 11 |
|
||||
12 12 | # default value in lambda parameters
|
||||
|
||||
unnecessary_lambda.py:10:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
||||
|
|
||||
9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda]
|
||||
10 | _ = lambda x, y: f(lambda x, y: x + y)(x, y) # [unnecessary-lambda]
|
||||
|
@ -72,5 +144,16 @@ unnecessary_lambda.py:10:5: PLW0108 Lambda may be unnecessary; consider inlining
|
|||
11 |
|
||||
12 | # default value in lambda parameters
|
||||
|
|
||||
= help: Inline function call
|
||||
|
||||
ℹ Unsafe fix
|
||||
7 7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||
8 8 |
|
||||
9 9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda]
|
||||
10 |-_ = lambda x, y: f(lambda x, y: x + y)(x, y) # [unnecessary-lambda]
|
||||
10 |+_ = f(lambda x, y: x + y) # [unnecessary-lambda]
|
||||
11 11 |
|
||||
12 12 | # default value in lambda parameters
|
||||
13 13 | _ = lambda x=42: print(x)
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue