mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +00:00
Make unnecessary-lambda
an always-unsafe fix (#10668)
## Summary See the linked issue and comment for more. Closes https://github.com/astral-sh/ruff/issues/10663.
This commit is contained in:
parent
7c2e9f71ea
commit
fc54f53662
2 changed files with 19 additions and 18 deletions
|
@ -1,6 +1,5 @@
|
|||
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;
|
||||
|
@ -27,15 +26,23 @@ use crate::checkers::ast::Checker;
|
|||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// This rule's fix is marked as unsafe in cases in which the lambda body itself
|
||||
/// contains an effect.
|
||||
/// This rule's fix is marked as unsafe for two primary reasons.
|
||||
///
|
||||
/// First, the lambda body itself could contain 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.
|
||||
/// However, even when the lambda body itself is pure, the lambda may
|
||||
/// change the argument names, which can lead to a change in behavior when
|
||||
/// callers pass arguments by name.
|
||||
///
|
||||
/// For example, replacing `foo = lambda x, y: func(x, y)` with `foo = func`,
|
||||
/// where `func` is defined as `def func(a, b): return a + b`, would be a
|
||||
/// breaking change for callers that execute the lambda by passing arguments by
|
||||
/// name, as in: `foo(x=1, y=2)`. Since `func` does not define the arguments
|
||||
/// `x` and `y`, unlike the lambda, the call would raise a `TypeError`.
|
||||
#[violation]
|
||||
pub struct UnnecessaryLambda;
|
||||
|
||||
|
@ -206,11 +213,7 @@ pub(crate) fn unnecessary_lambda(checker: &mut Checker, lambda: &ExprLambda) {
|
|||
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
|
||||
},
|
||||
Applicability::Unsafe,
|
||||
));
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ unnecessary_lambda.py:1:5: PLW0108 [*] Lambda may be unnecessary; consider inlin
|
|||
|
|
||||
= help: Inline function call
|
||||
|
||||
ℹ Safe fix
|
||||
ℹ Unsafe fix
|
||||
1 |-_ = lambda: print() # [unnecessary-lambda]
|
||||
1 |+_ = print # [unnecessary-lambda]
|
||||
2 2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
|
@ -26,7 +26,7 @@ unnecessary_lambda.py:2:5: PLW0108 [*] Lambda may be unnecessary; consider inlin
|
|||
|
|
||||
= help: Inline function call
|
||||
|
||||
ℹ Safe fix
|
||||
ℹ Unsafe fix
|
||||
1 1 | _ = lambda: print() # [unnecessary-lambda]
|
||||
2 |-_ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
2 |+_ = min # [unnecessary-lambda]
|
||||
|
@ -45,7 +45,7 @@ unnecessary_lambda.py:4:5: PLW0108 [*] Lambda may be unnecessary; consider inlin
|
|||
|
|
||||
= help: Inline function call
|
||||
|
||||
ℹ Safe fix
|
||||
ℹ Unsafe fix
|
||||
1 1 | _ = lambda: print() # [unnecessary-lambda]
|
||||
2 2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
3 3 |
|
||||
|
@ -65,7 +65,7 @@ unnecessary_lambda.py:5:5: PLW0108 [*] Lambda may be unnecessary; consider inlin
|
|||
|
|
||||
= help: Inline function call
|
||||
|
||||
ℹ Safe fix
|
||||
ℹ Unsafe fix
|
||||
2 2 | _ = lambda x, y: min(x, y) # [unnecessary-lambda]
|
||||
3 3 |
|
||||
4 4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
|
@ -85,7 +85,7 @@ unnecessary_lambda.py:6:5: PLW0108 [*] Lambda may be unnecessary; consider inlin
|
|||
|
|
||||
= help: Inline function call
|
||||
|
||||
ℹ Safe fix
|
||||
ℹ Unsafe fix
|
||||
3 3 |
|
||||
4 4 | _ = lambda *args: f(*args) # [unnecessary-lambda]
|
||||
5 5 | _ = lambda **kwargs: f(**kwargs) # [unnecessary-lambda]
|
||||
|
@ -106,7 +106,7 @@ unnecessary_lambda.py:7:5: PLW0108 [*] Lambda may be unnecessary; consider inlin
|
|||
|
|
||||
= help: Inline function call
|
||||
|
||||
ℹ Safe fix
|
||||
ℹ Unsafe 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]
|
||||
|
@ -155,5 +155,3 @@ unnecessary_lambda.py:10:5: PLW0108 [*] Lambda may be unnecessary; consider inli
|
|||
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