Skip to content

Commit d429822

Browse files
Fix unnecessary-lambda false positive for lambdas using its parameters in their body (#8498) (#8506)
Fixes #8496 (cherry picked from commit b621436) Co-authored-by: cherryblossom <[email protected]>
1 parent ebf1952 commit d429822

File tree

4 files changed

+26
-0
lines changed

4 files changed

+26
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
``unnecessary-lambda`` no longer warns on lambdas which use its parameters in
2+
their body (other than the final arguments), e.g.
3+
``lambda foo: (bar if foo else baz)(foo)``.
4+
5+
Closes #8496

pylint/checkers/base/basic_checker.py

+8
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ def _has_variadic_argument(
519519
)
520520

521521
@utils.only_required_for_messages("unnecessary-lambda")
522+
# pylint: disable-next=too-many-return-statements
522523
def visit_lambda(self, node: nodes.Lambda) -> None:
523524
"""Check whether the lambda is suspicious."""
524525
# if the body of the lambda is a call expression with the same
@@ -576,6 +577,13 @@ def visit_lambda(self, node: nodes.Lambda) -> None:
576577
if arg.name != passed_arg.name:
577578
return
578579

580+
# The lambda is necessary if it uses its parameter in the function it is
581+
# calling in the lambda's body
582+
# e.g. lambda foo: (func1 if foo else func2)(foo)
583+
for name in call.func.nodes_of_class(nodes.Name):
584+
if name.lookup(name.name)[0] is node:
585+
return
586+
579587
self.add_message("unnecessary-lambda", line=node.fromlineno, node=node)
580588

581589
@utils.only_required_for_messages("dangerous-default-value")

tests/functional/u/unnecessary/unnecessary_lambda.py

+11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
# +1: [unnecessary-lambda]
2525
_ = lambda x, y, z, *args, **kwargs: _ANYARGS(x, y, z, *args, **kwargs)
2626

27+
# These don't use their parameters in their body
28+
# +1: [unnecessary-lambda]
29+
_ = lambda x: z(lambda x: x)(x)
30+
# +1: [unnecessary-lambda]
31+
_ = lambda x, y: z(lambda x, y: x + y)(x, y)
32+
2733
# Lambdas that are *not* unnecessary and should *not* trigger warnings.
2834
_ = lambda x: x
2935
_ = lambda x: x()
@@ -50,3 +56,8 @@
5056
_ = lambda: code().analysis()
5157

5258
_ = lambda **kwargs: dict(bar=42, **kwargs)
59+
60+
# These use the lambda parameters in their body
61+
_ = lambda x: x(x)
62+
_ = lambda x, y: x(x, y)
63+
_ = lambda x: z(lambda y: x + y)(x)

tests/functional/u/unnecessary/unnecessary_lambda.txt

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ unnecessary-lambda:19:4:19:33:<lambda>:Lambda may not be necessary:UNDEFINED
55
unnecessary-lambda:21:4:21:39:<lambda>:Lambda may not be necessary:UNDEFINED
66
unnecessary-lambda:23:4:23:53:<lambda>:Lambda may not be necessary:UNDEFINED
77
unnecessary-lambda:25:4:25:71:<lambda>:Lambda may not be necessary:UNDEFINED
8+
unnecessary-lambda:29:4:29:31:<lambda>:Lambda may not be necessary:UNDEFINED
9+
unnecessary-lambda:31:4:31:44:<lambda>:Lambda may not be necessary:UNDEFINED

0 commit comments

Comments
 (0)