From fdf5beebe5ea5f7a7ca488c878030a9444f64e6c Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 22 Aug 2008 07:02:27 +0200 Subject: [PATCH] allow keyword arguments after *args in a function call (as Py3 does) some EncodedString name fixes for function names --- Cython/Compiler/Parsing.py | 51 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index b39bb2d7..396c4d6e 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -297,32 +297,37 @@ def p_call(s, function): keyword_args = [] star_arg = None starstar_arg = None - while s.sy not in ('*', '**', ')'): - arg = p_simple_expr(s) - if s.sy == '=': + while s.sy not in ('**', ')'): + if s.sy == '*': + if star_arg: + s.error("only one star-arg parameter allowed", + pos = s.position()) s.next() - if not arg.is_name: - s.error("Expected an identifier before '='", - pos = arg.pos) - encoded_name = EncodedString(arg.name) - keyword = ExprNodes.IdentifierStringNode(arg.pos, - value = encoded_name) - arg = p_simple_expr(s) - keyword_args.append((keyword, arg)) + star_arg = p_simple_expr(s) else: - if keyword_args: - s.error("Non-keyword arg following keyword arg", - pos = arg.pos) - positional_args.append(arg) + arg = p_simple_expr(s) + if s.sy == '=': + s.next() + if not arg.is_name: + s.error("Expected an identifier before '='", + pos = arg.pos) + encoded_name = EncodedString(arg.name) + keyword = ExprNodes.IdentifierStringNode(arg.pos, + value = encoded_name) + arg = p_simple_expr(s) + keyword_args.append((keyword, arg)) + else: + if keyword_args: + s.error("Non-keyword arg following keyword arg", + pos = arg.pos) + if star_arg: + s.error("Non-keyword arg following star-arg", + pos = arg.pos) + positional_args.append(arg) if s.sy != ',': break s.next() - if s.sy == '*': - s.next() - star_arg = p_simple_expr(s) - if s.sy == ',': - s.next() if s.sy == '**': s.next() starstar_arg = p_simple_expr(s) @@ -1738,7 +1743,7 @@ def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0, if s.sy == '(': s.next() if s.sy == ')' or looking_at_type(s): - base = Nodes.CNameDeclaratorNode(pos, name = "", cname = None) + base = Nodes.CNameDeclaratorNode(pos, name = EncodedString(u""), cname = None) result = p_c_func_declarator(s, pos, ctx, base, cmethod_flag) else: result = p_c_declarator(s, ctx, empty = empty, is_type = is_type, @@ -1808,7 +1813,7 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, else: rhs = None if s.sy == 'IDENT': - name = s.systring + name = EncodedString(s.systring) if is_type: s.add_type_name(name) if empty: @@ -2171,7 +2176,7 @@ def p_def_statement(s, decorators=None): # s.sy == 'def' pos = s.position() s.next() - name = p_ident(s) + name = EncodedString( p_ident(s) ) #args = [] s.expect('('); args = p_c_arg_list(s, in_pyfunc = 1, nonempty_declarators = 1) -- 2.26.2