Skip to content

Commit

Permalink
Implement unnecessary-direct-lambda-call (#1008)
Browse files Browse the repository at this point in the history
  • Loading branch information
harupy committed Dec 3, 2022
1 parent 3efa1a0 commit ebd2181
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -751,8 +751,9 @@ For more, see [Pylint](https://pypi.org/project/pylint/2.15.7/) on PyPI.
| Code | Name | Message | Fix |
| ---- | ---- | ------- | --- |
| PLE1142 | AwaitOutsideAsync | `await` should be used within an async function | |
| PLC3002 | UnnecessaryDirectLambdaCall | Lambda expression called directly. Execute the expression inline instead. | |
| PLR0206 | PropertyWithParameters | Cannot have defined parameters for properties | |
| PLE1142 | AwaitOutsideAsync | `await` should be used within an async function | |
### Ruff-specific rules
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Test unnecessary direct calls to lambda expressions."""
# pylint: disable=undefined-variable, line-too-long

y = (lambda x: x**2 + 2*x + 1)(a) # [unnecessary-direct-lambda-call]
y = max((lambda x: x**2)(a), (lambda x: x+1)(a)) # [unnecessary-direct-lambda-call,unnecessary-direct-lambda-call]
7 changes: 6 additions & 1 deletion src/check_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ where
}

if self.settings.enabled.contains(&CheckCode::PLR0206) {
pylint::plugins::property_with_parameters(self, stmt, decorator_list, args)
pylint::plugins::property_with_parameters(self, stmt, decorator_list, args);
}

self.check_builtin_shadowing(name, Range::from_located(stmt), true);
Expand Down Expand Up @@ -1712,6 +1712,11 @@ where
pygrep_hooks::checks::no_eval(self, func);
}

// pylint
if self.settings.enabled.contains(&CheckCode::PLC3002) {
pylint::plugins::unnecessary_direct_lambda_call(self, expr, func);
}

// Ruff
if self.settings.enabled.contains(&CheckCode::RUF101) {
rules::plugins::convert_exit_to_sys_exit(self, func);
Expand Down
8 changes: 8 additions & 0 deletions src/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub enum CheckCode {
F841,
F901,
// pylint errors
PLC3002,
PLR0206,
PLE1142,
// flake8-builtins
Expand Down Expand Up @@ -541,6 +542,7 @@ pub enum CheckKind {
UnusedVariable(String),
YieldOutsideFunction(DeferralKeyword),
// pylint errors
UnnecessaryDirectLambdaCall,
PropertyWithParameters,
AwaitOutsideAsync,
// flake8-builtins
Expand Down Expand Up @@ -827,6 +829,7 @@ impl CheckCode {
CheckCode::F841 => CheckKind::UnusedVariable("...".to_string()),
CheckCode::F901 => CheckKind::RaiseNotImplemented,
// pylint errors
CheckCode::PLC3002 => CheckKind::UnnecessaryDirectLambdaCall,
CheckCode::PLR0206 => CheckKind::PropertyWithParameters,
CheckCode::PLE1142 => CheckKind::AwaitOutsideAsync,
// flake8-builtins
Expand Down Expand Up @@ -1240,6 +1243,7 @@ impl CheckCode {
CheckCode::N817 => CheckCategory::PEP8Naming,
CheckCode::N818 => CheckCategory::PEP8Naming,
CheckCode::PGH001 => CheckCategory::PygrepHooks,
CheckCode::PLC3002 => CheckCategory::Pylint,
CheckCode::PLR0206 => CheckCategory::Pylint,
CheckCode::PLE1142 => CheckCategory::Pylint,
CheckCode::Q000 => CheckCategory::Flake8Quotes,
Expand Down Expand Up @@ -1354,6 +1358,7 @@ impl CheckKind {
CheckKind::NoNewLineAtEndOfFile => &CheckCode::W292,
CheckKind::InvalidEscapeSequence(_) => &CheckCode::W605,
// pylint errors
CheckKind::UnnecessaryDirectLambdaCall => &CheckCode::PLC3002,
CheckKind::PropertyWithParameters => &CheckCode::PLR0206,
CheckKind::AwaitOutsideAsync => &CheckCode::PLE1142,
// flake8-builtins
Expand Down Expand Up @@ -1728,6 +1733,9 @@ impl CheckKind {
format!("Invalid escape sequence: '\\{char}'")
}
// pylint errors
CheckKind::UnnecessaryDirectLambdaCall => "Lambda expression called directly. Execute \
the expression inline instead."
.to_string(),
CheckKind::PropertyWithParameters => {
"Cannot have defined parameters for properties".to_string()
}
Expand Down
16 changes: 16 additions & 0 deletions src/checks_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ pub enum CheckCodePrefix {
PGH0,
PGH00,
PGH001,
PLC,
PLC3,
PLC30,
PLC300,
PLC3002,
PLE,
PLE1,
PLE11,
Expand Down Expand Up @@ -1161,6 +1166,11 @@ impl CheckCodePrefix {
CheckCodePrefix::PGH0 => vec![CheckCode::PGH001],
CheckCodePrefix::PGH00 => vec![CheckCode::PGH001],
CheckCodePrefix::PGH001 => vec![CheckCode::PGH001],
CheckCodePrefix::PLC => vec![CheckCode::PLC3002],
CheckCodePrefix::PLC3 => vec![CheckCode::PLC3002],
CheckCodePrefix::PLC30 => vec![CheckCode::PLC3002],
CheckCodePrefix::PLC300 => vec![CheckCode::PLC3002],
CheckCodePrefix::PLC3002 => vec![CheckCode::PLC3002],
CheckCodePrefix::PLE => vec![CheckCode::PLE1142],
CheckCodePrefix::PLE1 => vec![CheckCode::PLE1142],
CheckCodePrefix::PLE11 => vec![CheckCode::PLE1142],
Expand Down Expand Up @@ -1637,6 +1647,11 @@ impl CheckCodePrefix {
CheckCodePrefix::PGH0 => SuffixLength::One,
CheckCodePrefix::PGH00 => SuffixLength::Two,
CheckCodePrefix::PGH001 => SuffixLength::Three,
CheckCodePrefix::PLC => SuffixLength::Zero,
CheckCodePrefix::PLC3 => SuffixLength::One,
CheckCodePrefix::PLC30 => SuffixLength::Two,
CheckCodePrefix::PLC300 => SuffixLength::Three,
CheckCodePrefix::PLC3002 => SuffixLength::Four,
CheckCodePrefix::PLE => SuffixLength::Zero,
CheckCodePrefix::PLE1 => SuffixLength::One,
CheckCodePrefix::PLE11 => SuffixLength::Two,
Expand Down Expand Up @@ -1741,6 +1756,7 @@ pub const CATEGORIES: &[CheckCodePrefix] = &[
CheckCodePrefix::M,
CheckCodePrefix::N,
CheckCodePrefix::PGH,
CheckCodePrefix::PLC,
CheckCodePrefix::PLE,
CheckCodePrefix::PLR,
CheckCodePrefix::Q,
Expand Down
1 change: 1 addition & 0 deletions src/pylint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod tests {
use crate::linter::test_path;
use crate::Settings;

#[test_case(CheckCode::PLC3002, Path::new("unnecessary_direct_lambda_call.py"); "PLC3002")]
#[test_case(CheckCode::PLR0206, Path::new("property_with_parameters.py"); "PLR0206")]
#[test_case(CheckCode::PLE1142, Path::new("await_outside_async.py"); "PLE1142")]
fn checks(check_code: CheckCode, path: &Path) -> Result<()> {
Expand Down
10 changes: 10 additions & 0 deletions src/pylint/plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ use crate::check_ast::Checker;
use crate::checks::CheckKind;
use crate::Check;

/// PLC3002
pub fn unnecessary_direct_lambda_call(checker: &mut Checker, expr: &Expr, func: &Expr) {
if let ExprKind::Lambda { .. } = &func.node {
checker.add_check(Check::new(
CheckKind::UnnecessaryDirectLambdaCall,
Range::from_located(expr),
));
}
}

/// PLR0206
pub fn property_with_parameters(
checker: &mut Checker,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
source: src/pylint/mod.rs
expression: checks
---
- kind: UnnecessaryDirectLambdaCall
location:
row: 4
column: 4
end_location:
row: 4
column: 33
fix: ~
- kind: UnnecessaryDirectLambdaCall
location:
row: 5
column: 8
end_location:
row: 5
column: 27
fix: ~
- kind: UnnecessaryDirectLambdaCall
location:
row: 5
column: 29
end_location:
row: 5
column: 47
fix: ~

0 comments on commit ebd2181

Please sign in to comment.