Skip to content

Commit

Permalink
Fix false positive for unnecessary-lambda. (#9149) (#9200)
Browse files Browse the repository at this point in the history
This simplifies the check for the call having kwargs but not the lambda.

(cherry picked from commit 2289c71)

Co-authored-by: Clément Schreiner <[email protected]>
  • Loading branch information
github-actions[bot] and clemux authored Oct 29, 2023
1 parent 53d4541 commit 0273db7
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 13 deletions.
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/9148.false_positive
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed false positive for ``unnecessary-lambda`` when the call has keyword arguments but not the lambda.

Closes #9148
16 changes: 3 additions & 13 deletions pylint/checkers/base/basic_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,6 @@ def _has_variadic_argument(
)

@utils.only_required_for_messages("unnecessary-lambda")
# pylint: disable-next=too-many-return-statements
def visit_lambda(self, node: nodes.Lambda) -> None:
"""Check whether the lambda is suspicious."""
# if the body of the lambda is a call expression with the same
Expand All @@ -544,29 +543,20 @@ def visit_lambda(self, node: nodes.Lambda) -> None:
# return something else (but we don't check that, yet).
return

call_site = astroid.arguments.CallSite.from_call(call)
ordinary_args = list(node.args.args)
new_call_args = list(self._filter_vararg(node, call.args))
if node.args.kwarg:
if self._has_variadic_argument(call.kwargs, node.args.kwarg):
if self._has_variadic_argument(call.keywords, node.args.kwarg):
return
elif call.keywords:
return

if node.args.vararg:
if self._has_variadic_argument(call.starargs, node.args.vararg):
return
elif call.starargs:
return

if call.keywords:
# Look for additional keyword arguments that are not part
# of the lambda's signature
lambda_kwargs = {keyword.name for keyword in node.args.defaults}
if len(lambda_kwargs) != len(call_site.keyword_arguments):
# Different lengths, so probably not identical
return
if set(call_site.keyword_arguments).difference(lambda_kwargs):
return

# The "ordinary" arguments must be in a correspondence such that:
# ordinary_args[i].name == call.args[i].name.
if len(ordinary_args) != len(new_call_args):
Expand Down
4 changes: 4 additions & 0 deletions tests/functional/u/unnecessary/unnecessary_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
_ = lambda: _ANYARGS(*[3], **{'three': 3})
_ = lambda: _ANYARGS(func=42)

# pylint: disable=missing-function-docstring
def f(d):
print(lambda x: str(x, **d))

# Don't warn about this.
_ = lambda: code().analysis()

Expand Down

0 comments on commit 0273db7

Please sign in to comment.