diff --git a/parso/python/normalizer.py b/parso/python/normalizer.py index 697ecba..3880966 100644 --- a/parso/python/normalizer.py +++ b/parso/python/normalizer.py @@ -255,8 +255,14 @@ class ErrorFinder(Normalizer): self._add_syntax_error(message, node) break elif node.type in ('parameters', 'lambdef'): + param_names = set() default_only = False for p in _iter_params(node): + if p.name.value in param_names: + message = "duplicate argument '%s' in function definition" + self._add_syntax_error(message % p.name.value, p.name) + param_names.add(p.name.value) + if p.default is None: if default_only: # def f(x=3, y): pass diff --git a/test/test_python_errors.py b/test/test_python_errors.py index 94a1211..82031f5 100644 --- a/test/test_python_errors.py +++ b/test/test_python_errors.py @@ -101,6 +101,9 @@ def test_indentation_errors(code, positions): 'f(**x, *y)', 'f(**x, y=3, z)', + # SyntaxErrors from Python/symtable.c + 'def f(x, x): pass', + # IndentationError ' foo', 'def x():\n 1\n 2', @@ -121,8 +124,11 @@ def test_python_exception_matches(code): if sys.version_info[:2] == (2, 6) and wanted == 'SyntaxError: unexpected EOF while parsing': wanted = 'SyntaxError: invalid syntax' - error, = _get_error_list(code) - assert wanted == error.message + errors = _get_error_list(code) + actual = None + if errors: + actual = errors[0].message + assert wanted == actual @pytest.mark.parametrize(