Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make lambda-assignment fix always-manual in class bodies #6626

Merged
merged 1 commit into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions crates/ruff/resources/test/fixtures/pycodestyle/E731.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
9 changes: 6 additions & 3 deletions crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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