Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@
# lambda uses an additional keyword
_ = lambda *args: f(*args, y=1)
_ = lambda *args: f(*args, y=x)

# https://github.com/astral-sh/ruff/issues/18675
_ = lambda x: (string := str)(x)
_ = lambda x: ((x := 1) and str)(x)
37 changes: 31 additions & 6 deletions crates/ruff_linter/src/rules/pylint/rules/unnecessary_lambda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ruff_python_ast::{self as ast, Expr, ExprLambda, Parameter, ParameterWithDef
use ruff_text_size::Ranged;

use crate::checkers::ast::Checker;
use crate::{AlwaysFixableViolation, Applicability, Edit, Fix};
use crate::{Applicability, Edit, Fix, FixAvailability, Violation};

/// ## What it does
/// Checks for `lambda` definitions that consist of a single function call
Expand Down Expand Up @@ -46,14 +46,16 @@ use crate::{AlwaysFixableViolation, Applicability, Edit, Fix};
#[derive(ViolationMetadata)]
pub(crate) struct UnnecessaryLambda;

impl AlwaysFixableViolation for UnnecessaryLambda {
impl Violation for UnnecessaryLambda {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;

#[derive_message_formats]
fn message(&self) -> String {
"Lambda may be unnecessary; consider inlining inner function".to_string()
}

fn fix_title(&self) -> String {
"Inline function call".to_string()
fn fix_title(&self) -> Option<String> {
Some("Inline function call".to_string())
}
}

Expand Down Expand Up @@ -199,7 +201,7 @@ pub(crate) fn unnecessary_lambda(checker: &Checker, lambda: &ExprLambda) {
finder.names
};

for name in names {
for name in &names {
if let Some(binding_id) = checker.semantic().resolve_name(name) {
let binding = checker.semantic().binding(binding_id);
if checker.semantic().is_current_scope(binding.scope) {
Expand All @@ -209,9 +211,32 @@ pub(crate) fn unnecessary_lambda(checker: &Checker, lambda: &ExprLambda) {
}

let mut diagnostic = checker.report_diagnostic(UnnecessaryLambda, lambda.range());
// Suppress the fix if the assignment expression target shadows one of the lambda's parameters.
// This is necessary to avoid introducing a change in the behavior of the program.
for name in names {
if let Some(binding_id) = checker.semantic().lookup_symbol(name.id()) {
let binding = checker.semantic().binding(binding_id);
if checker
.semantic()
.current_scope()
.shadowed_binding(binding_id)
.is_some()
&& binding
.expression(checker.semantic())
.is_some_and(Expr::is_named_expr)
{
return;
}
}
}

diagnostic.set_fix(Fix::applicable_edit(
Edit::range_replacement(
checker.locator().slice(func.as_ref()).to_string(),
if matches!(func.as_ref(), Expr::Named(_)) {
format!("({})", checker.locator().slice(func.as_ref()))
} else {
checker.locator().slice(func.as_ref()).to_string()
},
lambda.range(),
),
Applicability::Unsafe,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,29 @@ 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)

unnecessary_lambda.py:62:5: PLW0108 [*] Lambda may be unnecessary; consider inlining inner function
|
61 | # https://github.com/astral-sh/ruff/issues/18675
62 | _ = lambda x: (string := str)(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108
63 | _ = lambda x: ((x := 1) and str)(x)
|
= help: Inline function call

ℹ Unsafe fix
59 59 | _ = lambda *args: f(*args, y=x)
60 60 |
61 61 | # https://github.com/astral-sh/ruff/issues/18675
62 |-_ = lambda x: (string := str)(x)
62 |+_ = (string := str)
63 63 | _ = lambda x: ((x := 1) and str)(x)

unnecessary_lambda.py:63:5: PLW0108 Lambda may be unnecessary; consider inlining inner function
|
61 | # https://github.com/astral-sh/ruff/issues/18675
62 | _ = lambda x: (string := str)(x)
63 | _ = lambda x: ((x := 1) and str)(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLW0108
|
= help: Inline function call
Loading