mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:21 +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_macros::{derive_message_formats, violation};
|
||||||
|
use ruff_python_ast::helpers::contains_effect;
|
||||||
use ruff_python_ast::visitor::Visitor;
|
use ruff_python_ast::visitor::Visitor;
|
||||||
use ruff_python_ast::{self as ast, visitor, Expr, ExprLambda, Parameter, ParameterWithDefault};
|
use ruff_python_ast::{self as ast, visitor, Expr, ExprLambda, Parameter, ParameterWithDefault};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
@ -24,14 +25,29 @@ use crate::checkers::ast::Checker;
|
||||||
/// ```python
|
/// ```python
|
||||||
/// df.apply(str)
|
/// 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]
|
#[violation]
|
||||||
pub struct UnnecessaryLambda;
|
pub struct UnnecessaryLambda;
|
||||||
|
|
||||||
impl Violation for UnnecessaryLambda {
|
impl AlwaysFixableViolation for UnnecessaryLambda {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
format!("Lambda may be unnecessary; consider inlining inner function")
|
format!("Lambda may be unnecessary; consider inlining inner function")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fix_title(&self) -> String {
|
||||||
|
"Inline function call".to_string()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PLW0108
|
/// PLW0108
|
||||||
|
@ -184,9 +200,19 @@ pub(crate) fn unnecessary_lambda(checker: &mut Checker, lambda: &ExprLambda) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checker
|
let mut diagnostic = Diagnostic::new(UnnecessaryLambda, lambda.range());
|
||||||
.diagnostics
|
diagnostic.set_fix(Fix::applicable_edit(
|
||||||
.push(Diagnostic::new(UnnecessaryLambda, lambda.range()));
|
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.
|
/// Identify all `Expr::Name` nodes in an AST.
|
||||||
|
|
|
@ -1,14 +1,22 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
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]
|
1 | _ = lambda: print() # [unnecessary-lambda]
|
||||||
| ^^^^^^^^^^^^^^^ PLW0108
|
| ^^^^^^^^^^^^^^^ PLW0108
|
||||||
2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
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]
|
1 | _ = lambda: print() # [unnecessary-lambda]
|
||||||
2 | _ = lambda x, y: min(x, y) # [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 |
|
3 |
|
||||||
4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
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]
|
2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||||
3 |
|
3 |
|
||||||
|
@ -26,8 +43,19 @@ unnecessary_lambda.py:4:5: PLW0108 Lambda may be unnecessary; consider inlining
|
||||||
5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||||
6 | _ = lambda *args, **kwargs: f(*args, **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]
|
4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||||
5 | _ = lambda **kwargs: f(**kwargs) # [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]
|
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 | _ = 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]
|
4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||||
5 | _ = lambda **kwargs: f(**kwargs) # [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
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108
|
||||||
7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *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: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]
|
5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||||
6 | _ = lambda *args, **kwargs: f(*args, **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 |
|
8 |
|
||||||
9 | _ = lambda x: f(lambda x: x)(x) # [unnecessary-lambda]
|
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]
|
7 | _ = lambda x, y, z, *args, **kwargs: f(x, y, z, *args, **kwargs) # [unnecessary-lambda]
|
||||||
8 |
|
8 |
|
||||||
|
@ -63,8 +124,19 @@ unnecessary_lambda.py:9:5: PLW0108 Lambda may be unnecessary; consider inlining
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108
|
||||||
10 | _ = lambda x, y: f(lambda x, y: x + y)(x, y) # [unnecessary-lambda]
|
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]
|
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 | _ = 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 |
|
11 |
|
||||||
12 | # default value in lambda parameters
|
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