From 0273db7fb4b77c882e40cd766c61a56a0cb2b8e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 29 Oct 2023 19:45:28 +0000 Subject: [PATCH] Fix false positive for ``unnecessary-lambda``. (#9149) (#9200) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simplifies the check for the call having kwargs but not the lambda. (cherry picked from commit 2289c7156638dc64c49d149e0bdd23f50fc471a4) Co-authored-by: Clément Schreiner --- doc/whatsnew/fragments/9148.false_positive | 3 +++ pylint/checkers/base/basic_checker.py | 16 +++------------- .../u/unnecessary/unnecessary_lambda.py | 4 ++++ 3 files changed, 10 insertions(+), 13 deletions(-) create mode 100644 doc/whatsnew/fragments/9148.false_positive diff --git a/doc/whatsnew/fragments/9148.false_positive b/doc/whatsnew/fragments/9148.false_positive new file mode 100644 index 0000000000..647deb103e --- /dev/null +++ b/doc/whatsnew/fragments/9148.false_positive @@ -0,0 +1,3 @@ +Fixed false positive for ``unnecessary-lambda`` when the call has keyword arguments but not the lambda. + +Closes #9148 diff --git a/pylint/checkers/base/basic_checker.py b/pylint/checkers/base/basic_checker.py index 3505ee7082..8aaa274d65 100644 --- a/pylint/checkers/base/basic_checker.py +++ b/pylint/checkers/base/basic_checker.py @@ -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 @@ -544,12 +543,13 @@ 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): @@ -557,16 +557,6 @@ def visit_lambda(self, node: nodes.Lambda) -> None: 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): diff --git a/tests/functional/u/unnecessary/unnecessary_lambda.py b/tests/functional/u/unnecessary/unnecessary_lambda.py index 82571a4444..85c30fef28 100644 --- a/tests/functional/u/unnecessary/unnecessary_lambda.py +++ b/tests/functional/u/unnecessary/unnecessary_lambda.py @@ -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()