diff --git a/doc/whatsnew/fragments/9669.false_negative b/doc/whatsnew/fragments/9669.false_negative new file mode 100644 index 0000000000..5c16ef7bd9 --- /dev/null +++ b/doc/whatsnew/fragments/9669.false_negative @@ -0,0 +1,3 @@ +Fix a false negative for ``duplicate-argument-name`` by including ``positional-only``, ``*args`` and ``**kwargs`` arguments in the check. + +Closes #9669 diff --git a/pylint/checkers/base/basic_error_checker.py b/pylint/checkers/base/basic_error_checker.py index e58be23096..daa71f9557 100644 --- a/pylint/checkers/base/basic_error_checker.py +++ b/pylint/checkers/base/basic_error_checker.py @@ -145,7 +145,7 @@ class BasicErrorChecker(_BasicChecker): "pre-decrement operator -- and ++, which doesn't exist in Python.", ), "E0108": ( - "Duplicate argument name %s in function definition", + "Duplicate argument name %r in function definition", "duplicate-argument-name", "Duplicate argument names in function definitions are syntax errors.", ), @@ -285,8 +285,8 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None: self.add_message("return-in-init", node=node) # Check for duplicate names by clustering args with same name for detailed report arg_clusters = {} - arguments: Iterator[Any] = filter(None, [node.args.args, node.args.kwonlyargs]) - for arg in itertools.chain.from_iterable(arguments): + arguments: Iterator[Any] = node.args.arguments + for arg in arguments: if arg.name in arg_clusters: self.add_message( "duplicate-argument-name", diff --git a/tests/functional/d/duplicate/duplicate_argument_name.py b/tests/functional/d/duplicate/duplicate_argument_name.py index c0c68b43bb..7dbc113754 100644 --- a/tests/functional/d/duplicate/duplicate_argument_name.py +++ b/tests/functional/d/duplicate/duplicate_argument_name.py @@ -1,14 +1,23 @@ """Check for duplicate function arguments.""" +# pylint: disable=missing-docstring, line-too-long + def foo1(_, _): # [duplicate-argument-name] - """Function with duplicate argument name.""" + ... def foo2(_abc, *, _abc): # [duplicate-argument-name] - """Function with duplicate argument name.""" + ... def foo3(_, _=3): # [duplicate-argument-name] - """Function with duplicate argument name.""" + ... def foo4(_, *, _): # [duplicate-argument-name] - """Function with duplicate argument name.""" + ... + +def foo5(_, *_, _=3): # [duplicate-argument-name, duplicate-argument-name] + ... + +# +1: [duplicate-argument-name, duplicate-argument-name, duplicate-argument-name, duplicate-argument-name] +def foo6(_, /, _, *_, _="_", **_): + ... diff --git a/tests/functional/d/duplicate/duplicate_argument_name.txt b/tests/functional/d/duplicate/duplicate_argument_name.txt index 2925c5ac40..e80f2211e8 100644 --- a/tests/functional/d/duplicate/duplicate_argument_name.txt +++ b/tests/functional/d/duplicate/duplicate_argument_name.txt @@ -1,4 +1,10 @@ -duplicate-argument-name:4:12:4:13:foo1:Duplicate argument name _ in function definition:HIGH -duplicate-argument-name:7:18:7:22:foo2:Duplicate argument name _abc in function definition:HIGH -duplicate-argument-name:10:12:10:13:foo3:Duplicate argument name _ in function definition:HIGH -duplicate-argument-name:13:15:13:16:foo4:Duplicate argument name _ in function definition:HIGH +duplicate-argument-name:6:12:6:13:foo1:Duplicate argument name '_' in function definition:HIGH +duplicate-argument-name:9:18:9:22:foo2:Duplicate argument name '_abc' in function definition:HIGH +duplicate-argument-name:12:12:12:13:foo3:Duplicate argument name '_' in function definition:HIGH +duplicate-argument-name:15:15:15:16:foo4:Duplicate argument name '_' in function definition:HIGH +duplicate-argument-name:18:13:18:14:foo5:Duplicate argument name '_' in function definition:HIGH +duplicate-argument-name:18:16:18:17:foo5:Duplicate argument name '_' in function definition:HIGH +duplicate-argument-name:22:15:22:16:foo6:Duplicate argument name '_' in function definition:HIGH +duplicate-argument-name:22:19:22:20:foo6:Duplicate argument name '_' in function definition:HIGH +duplicate-argument-name:22:22:22:23:foo6:Duplicate argument name '_' in function definition:HIGH +duplicate-argument-name:22:31:22:32:foo6:Duplicate argument name '_' in function definition:HIGH diff --git a/tests/functional/d/duplicate/duplicate_argument_name_py3.py b/tests/functional/d/duplicate/duplicate_argument_name_py3.py deleted file mode 100644 index 4751c6f2d3..0000000000 --- a/tests/functional/d/duplicate/duplicate_argument_name_py3.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Check for duplicate function keywordonly arguments.""" - - -def foo1(_, *_, _=3): # [duplicate-argument-name] - """Function with duplicate argument name.""" diff --git a/tests/functional/d/duplicate/duplicate_argument_name_py3.txt b/tests/functional/d/duplicate/duplicate_argument_name_py3.txt deleted file mode 100644 index 3d6f6f8d9d..0000000000 --- a/tests/functional/d/duplicate/duplicate_argument_name_py3.txt +++ /dev/null @@ -1 +0,0 @@ -duplicate-argument-name:4:16:4:17:foo1:Duplicate argument name _ in function definition:HIGH