From 1655c1ccf28de9e215f5336c2b5d6afc969a000c Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 16 Aug 2023 13:40:19 -0400 Subject: [PATCH] Make lambda-assignment fix always-manual in class bodies --- .../test/fixtures/pycodestyle/E731.py | 5 +++ .../pycodestyle/rules/lambda_assignment.rs | 9 +++-- ...les__pycodestyle__tests__E731_E731.py.snap | 40 ++++++++++++++++++- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/pycodestyle/E731.py b/crates/ruff/resources/test/fixtures/pycodestyle/E731.py index c207c7dae9262..2cb4c7ea3acb4 100644 --- a/crates/ruff/resources/test/fixtures/pycodestyle/E731.py +++ b/crates/ruff/resources/test/fixtures/pycodestyle/E731.py @@ -133,3 +133,8 @@ def scope(): from collections.abc import Callable f: Callable[[str, int, list[str]], list[str]] = lambda a, b, /, c: [*c, a * b] + + +class TemperatureScales(Enum): + CELSIUS = (lambda deg_c: deg_c) + FAHRENHEIT = (lambda deg_c: deg_c * 9 / 5 + 32) diff --git a/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs b/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs index d06d032d4ea24..66b90caeab350 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs @@ -112,11 +112,14 @@ pub(crate) fn lambda_assignment( // If the assignment is in a class body, it might not be safe to replace it because the // assignment might be carrying a type annotation that will be used by some package like // dataclasses, which wouldn't consider the rewritten function definition to be - // equivalent. Similarly, if the lambda is shadowing a variable in the current scope, - // rewriting it as a function declaration may break type-checking. + // equivalent. Even if it _doesn't_ have an annotation, rewriting safely would require + // making this a static method. // See: https://github.com/astral-sh/ruff/issues/3046 + // + // Similarly, if the lambda is shadowing a variable in the current scope, + // rewriting it as a function declaration may break type-checking. // See: https://github.com/astral-sh/ruff/issues/5421 - if (annotation.is_some() && checker.semantic().current_scope().kind.is_class()) + if checker.semantic().current_scope().kind.is_class() || checker .semantic() .current_scope() diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E731_E731.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E731_E731.py.snap index 440cc87ebd689..39603bd0c2bb5 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E731_E731.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E731_E731.py.snap @@ -109,7 +109,7 @@ E731.py:57:5: E731 [*] Do not assign a `lambda` expression, use a `def` | = help: Rewrite `f` as a `def` -ℹ Suggested fix +ℹ Possible fix 54 54 | 55 55 | class Scope: 56 56 | # E731 @@ -318,5 +318,43 @@ E731.py:135:5: E731 [*] Do not assign a `lambda` expression, use a `def` 135 |- f: Callable[[str, int, list[str]], list[str]] = lambda a, b, /, c: [*c, a * b] 135 |+ def f(a: str, b: int, /, c: list[str]) -> list[str]: 136 |+ return [*c, a * b] +136 137 | +137 138 | +138 139 | class TemperatureScales(Enum): + +E731.py:139:5: E731 [*] Do not assign a `lambda` expression, use a `def` + | +138 | class TemperatureScales(Enum): +139 | CELSIUS = (lambda deg_c: deg_c) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E731 +140 | FAHRENHEIT = (lambda deg_c: deg_c * 9 / 5 + 32) + | + = help: Rewrite `CELSIUS` as a `def` + +ℹ Possible fix +136 136 | +137 137 | +138 138 | class TemperatureScales(Enum): +139 |- CELSIUS = (lambda deg_c: deg_c) + 139 |+ def CELSIUS(deg_c): + 140 |+ return deg_c +140 141 | FAHRENHEIT = (lambda deg_c: deg_c * 9 / 5 + 32) + +E731.py:140:5: E731 [*] Do not assign a `lambda` expression, use a `def` + | +138 | class TemperatureScales(Enum): +139 | CELSIUS = (lambda deg_c: deg_c) +140 | FAHRENHEIT = (lambda deg_c: deg_c * 9 / 5 + 32) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E731 + | + = help: Rewrite `FAHRENHEIT` as a `def` + +ℹ Possible fix +137 137 | +138 138 | class TemperatureScales(Enum): +139 139 | CELSIUS = (lambda deg_c: deg_c) +140 |- FAHRENHEIT = (lambda deg_c: deg_c * 9 / 5 + 32) + 140 |+ def FAHRENHEIT(deg_c): + 141 |+ return deg_c * 9 / 5 + 32