From 36fbb6cd3ea4faa518851a116fd6c6bfb9fc8c60 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 19 Jun 2014 12:18:24 +0200 Subject: [PATCH] reorder var_args if named arguments are in front of *args. --- jedi/evaluate/param.py | 24 +++++++++++++++++++++++- test/static_analysis/star_arguments.py | 6 ++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/jedi/evaluate/param.py b/jedi/evaluate/param.py index fe00a24d..7fdfdc70 100644 --- a/jedi/evaluate/param.py +++ b/jedi/evaluate/param.py @@ -197,7 +197,7 @@ def _unpack_var_args(evaluator, var_args, func): argument_list.append((None, [helpers.FakeStatement([func.instance])])) # `var_args` is typically an Array, and not a list. - for stmt in var_args: + for stmt in _reorder_var_args(var_args): if not isinstance(stmt, pr.Statement): if stmt is None: argument_list.append((None, [])) @@ -260,6 +260,28 @@ def _unpack_var_args(evaluator, var_args, func): return argument_list +def _reorder_var_args(var_args): + """ + Reordering var_args is necessary, because star args sometimes appear after + named argument, but in the actual order it's prepended. + """ + named_index = None + new_args = [] + for i, stmt in enumerate(var_args): + if named_index is None and stmt.assignment_details: + named_index = i + + if named_index is not None: + expression_list = stmt.expression_list() + if expression_list and expression_list[0] == '*': + new_args.insert(named_index, stmt) + named_index += 1 + continue + + new_args.append(stmt) + return new_args + + def _iterate_star_args(evaluator, array, expression_list, func): from jedi.evaluate.representation import Instance if isinstance(array, iterable.Array): diff --git a/test/static_analysis/star_arguments.py b/test/static_analysis/star_arguments.py index dc991036..e7989d26 100644 --- a/test/static_analysis/star_arguments.py +++ b/test/static_analysis/star_arguments.py @@ -32,6 +32,12 @@ nested_twice(2) #! 19 type-error-too-many-arguments nested_twice(2, 3, 4) + +# A named argument can be located before *args. +def star_args_with_named(*args): + return simple2(c='', *args) + +star_args_with_named(1, 2) # ----------------- # **kwargs # -----------------