summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pylint/checkers/base.py28
-rw-r--r--pylint/test/functional/async_functions.py2
-rw-r--r--pylint/test/functional/async_functions.txt1
-rw-r--r--pylint/test/functional/duplicate_argument_name.py9
-rw-r--r--pylint/test/functional/duplicate_argument_name.txt5
-rw-r--r--pylint/test/functional/duplicate_argument_name_py3.py5
-rw-r--r--pylint/test/functional/duplicate_argument_name_py3.rc2
-rw-r--r--pylint/test/functional/duplicate_argument_name_py3.txt3
8 files changed, 45 insertions, 10 deletions
diff --git a/pylint/checkers/base.py b/pylint/checkers/base.py
index cba7e3eb7..3b052de4e 100644
--- a/pylint/checkers/base.py
+++ b/pylint/checkers/base.py
@@ -531,13 +531,29 @@ class BasicErrorChecker(_BasicChecker):
retnode.value.value is not None:
self.add_message('return-arg-in-generator', node=node,
line=retnode.fromlineno)
- # Check for duplicate names
- args = set()
- for name in node.argnames():
- if name in args:
- self.add_message('duplicate-argument-name', node=node, args=(name,))
+ # Check for duplicate names by clustering args with same name for detailed report
+ args = node.args
+ arg_clusters = collections.defaultdict(list)
+ for arg in itertools.chain.from_iterable(pack for pack in
+ [args.args, [args.vararg],
+ args.kwonlyargs, [args.kwarg]]
+ if pack is not None and all(pack)):
+ if isinstance(arg, str):
+ # sadly, asteroid doesn't expose variadic and kw-variadic arg nodes
+ arg_clusters[arg].append(arg)
else:
- args.add(name)
+ arg_clusters[arg.name].append(arg)
+
+ # provide detailed report about each repeated argument
+ for arg in itertools.chain.from_iterable(args for args in arg_clusters.values()
+ if len(args) > 1):
+ if isinstance(arg, str):
+ # fallback on previous behavior
+ add_message_args = node.lineno, node, (arg,)
+ else:
+ add_message_args = arg.lineno, arg, (arg.name,)
+
+ self.add_message('duplicate-argument-name', *add_message_args)
visit_asyncfunctiondef = visit_functiondef
diff --git a/pylint/test/functional/async_functions.py b/pylint/test/functional/async_functions.py
index f8427d073..2f2252de8 100644
--- a/pylint/test/functional/async_functions.py
+++ b/pylint/test/functional/async_functions.py
@@ -53,7 +53,7 @@ async def complex_function(this, function, has, more, arguments, than,
pass
-# +1: [duplicate-argument-name,dangerous-default-value]
+# +1: [duplicate-argument-name, duplicate-argument-name, dangerous-default-value]
async def func(a, a, b=[]):
return a, b
diff --git a/pylint/test/functional/async_functions.txt b/pylint/test/functional/async_functions.txt
index 94a66783e..e00c5bbfa 100644
--- a/pylint/test/functional/async_functions.txt
+++ b/pylint/test/functional/async_functions.txt
@@ -6,5 +6,6 @@ too-many-branches:26:complex_function:Too many branches (13/12)
too-many-return-statements:26:complex_function:Too many return statements (10/6)
dangerous-default-value:57:func:Dangerous default value [] as argument
duplicate-argument-name:57:func:Duplicate argument name a in function definition
+duplicate-argument-name:57:func:Duplicate argument name a in function definition
blacklisted-name:62:foo:Black listed name "foo"
empty-docstring:62:foo:Empty function docstring \ No newline at end of file
diff --git a/pylint/test/functional/duplicate_argument_name.py b/pylint/test/functional/duplicate_argument_name.py
index 2b939ed56..e9431ae0f 100644
--- a/pylint/test/functional/duplicate_argument_name.py
+++ b/pylint/test/functional/duplicate_argument_name.py
@@ -1,11 +1,14 @@
"""Check for duplicate function arguments."""
-def foo1(_, _): # [duplicate-argument-name]
+def foo1(_, _): # [duplicate-argument-name, duplicate-argument-name]
"""Function with duplicate argument name."""
-def foo2(_, *_): # [duplicate-argument-name]
+def foo2(_, *_): # [duplicate-argument-name, duplicate-argument-name]
"""Function with duplicate argument name."""
-def foo3(_, _=3): # [duplicate-argument-name]
+def foo3(_, _=3): # [duplicate-argument-name, duplicate-argument-name]
+ """Function with duplicate argument name."""
+
+def foo4(_, **_): # [duplicate-argument-name, duplicate-argument-name]
"""Function with duplicate argument name."""
diff --git a/pylint/test/functional/duplicate_argument_name.txt b/pylint/test/functional/duplicate_argument_name.txt
index c51e4dfcc..6686dd91b 100644
--- a/pylint/test/functional/duplicate_argument_name.txt
+++ b/pylint/test/functional/duplicate_argument_name.txt
@@ -1,3 +1,8 @@
duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition
+duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition
+duplicate-argument-name:7:foo2:Duplicate argument name _ in function definition
duplicate-argument-name:7:foo2:Duplicate argument name _ in function definition
duplicate-argument-name:10:foo3:Duplicate argument name _ in function definition
+duplicate-argument-name:10:foo3:Duplicate argument name _ in function definition
+duplicate-argument-name:13:foo4:Duplicate argument name _ in function definition
+duplicate-argument-name:13:foo4:Duplicate argument name _ in function definition \ No newline at end of file
diff --git a/pylint/test/functional/duplicate_argument_name_py3.py b/pylint/test/functional/duplicate_argument_name_py3.py
new file mode 100644
index 000000000..6990d929c
--- /dev/null
+++ b/pylint/test/functional/duplicate_argument_name_py3.py
@@ -0,0 +1,5 @@
+"""Check for duplicate function keywordonly arguments."""
+
+
+def foo1(_, *_, _=3): # [duplicate-argument-name, duplicate-argument-name, duplicate-argument-name]
+ """Function with duplicate argument name."""
diff --git a/pylint/test/functional/duplicate_argument_name_py3.rc b/pylint/test/functional/duplicate_argument_name_py3.rc
new file mode 100644
index 000000000..a2ab06c50
--- /dev/null
+++ b/pylint/test/functional/duplicate_argument_name_py3.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.0 \ No newline at end of file
diff --git a/pylint/test/functional/duplicate_argument_name_py3.txt b/pylint/test/functional/duplicate_argument_name_py3.txt
new file mode 100644
index 000000000..03e824446
--- /dev/null
+++ b/pylint/test/functional/duplicate_argument_name_py3.txt
@@ -0,0 +1,3 @@
+duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition
+duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition
+duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition \ No newline at end of file