From 80e43a95da6fd3dc5882f7c77d3fb13b2666df4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Perrin?= Date: Wed, 15 Dec 2021 00:51:50 +0900 Subject: typecheck: simplify variadic positional detection (#5417) The isinstance checks were not necessary here and caused several false positives where a function with variadic positional argument was called, like for example when the call is used as a function argument, in a if, while or with statement. Co-authored-by: Pierre Sassoulas --- CONTRIBUTORS.txt | 2 ++ ChangeLog | 5 ++++ pylint/checkers/typecheck.py | 12 +--------- .../regression_no_value_for_parameter.py | 28 +++++++++++++++++++--- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 54e31c617..f50f8e470 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -581,6 +581,8 @@ contributors: * Harshil (harshil21): contributor +* Jérome Perrin (perrinjerome): contributor + * Felix von Drigalski (felixvd): contributor * Philipp Albrecht (pylbrecht): contributor diff --git a/ChangeLog b/ChangeLog index df21f26c8..265ac67a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,11 @@ Release date: TBA * Some files in ``pylint.testutils`` were deprecated. In the future imports should be done from the ``pylint.testutils.functional`` namespace directly. +* Fixed false positives for ``no-value-for-parameter`` with variadic + positional arguments. + + Closes #5416 + * ``safe_infer`` no longer makes an inference when given two function definitions with differing numbers of arguments. diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index f29f4f3e1..c5203adf7 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -630,17 +630,7 @@ def _no_context_variadic_keywords(node, scope): def _no_context_variadic_positional(node, scope): - variadics = () - if isinstance(scope, nodes.Lambda) and not isinstance(scope, nodes.FunctionDef): - variadics = node.starargs + node.kwargs - else: - statement = node.statement() - if isinstance( - statement, (nodes.Expr, nodes.Return, nodes.Assign) - ) and isinstance(statement.value, nodes.Call): - call = statement.value - variadics = call.starargs + call.kwargs - + variadics = node.starargs + node.kwargs return _no_context_variadic(node, scope.args.vararg, nodes.Starred, variadics) diff --git a/tests/functional/r/regression/regression_no_value_for_parameter.py b/tests/functional/r/regression/regression_no_value_for_parameter.py index 6dd2ea491..d9675e614 100644 --- a/tests/functional/r/regression/regression_no_value_for_parameter.py +++ b/tests/functional/r/regression/regression_no_value_for_parameter.py @@ -28,9 +28,20 @@ def varargs_good(*parts): def varargs_no_expr(*parts): - """False positive below this line""" + """False positives below this line""" ret = os.path.join(*parts) - return ret + if ret: + return ret + print(os.path.join(*parts)) + if os.path.join(*parts): + print() + elif os.path.join(*parts): + print() + while os.path.join(*parts): + print() + with os.path.join(*parts): # pylint:disable=not-context-manager + print() + return os.path.join(*parts) + os.path.join(*parts) - os.path.join(*parts) def kwargs_good(**kwargs): @@ -39,4 +50,15 @@ def kwargs_good(**kwargs): def kwargs_no_expr(**kwargs): ret = func(**kwargs) - return ret + if ret: + return ret + print(func(**kwargs)) + if func(**kwargs): + print() + elif func(**kwargs): + print() + while func(**kwargs): + print() + with func(**kwargs): # pylint:disable=not-context-manager + print() + return func(**kwargs) + func(**kwargs) - func(**kwargs) -- cgit v1.2.1