Commits

Amaury Forgeot d'Arc committed 16f4dc1

Update grammar and compiler to recognize (and skip for now)
the single * used to separate keywords-only arguments

  • Participants
  • Parent commits caa6a02
  • Branches py3k

Comments (0)

Files changed (3)

pypy/interpreter/astcompiler/astbuilder.py

         while i < child_count:
             argument = arguments_node.children[i]
             arg_type = argument.type
-            if arg_type == syms.fpdef:
+            if arg_type == syms.tfpdef:
                 parenthesized = False
                 complex_args = False
                 while True:
                     break
             elif arg_type == tokens.STAR:
                 name_node = arguments_node.children[i + 1]
-                variable_arg = name_node.value
-                self.check_forbidden_name(variable_arg, name_node)
-                i += 3
+                if name_node.type == tokens.COMMA:
+                    # XXX for now
+                    i += 2
+                else:
+                    variable_arg = name_node.children[0].value
+                    self.check_forbidden_name(variable_arg, name_node)
+                    i += 3
             elif arg_type == tokens.DOUBLESTAR:
                 name_node = arguments_node.children[i + 1]
-                keywords_arg = name_node.value
+                keywords_arg = name_node.children[0].value
                 self.check_forbidden_name(keywords_arg, name_node)
                 i += 3
             else:

pypy/interpreter/astcompiler/test/test_compiler.py

         yield self.st, func, "f(0)", 0
 
     def test_argtuple(self):
-        yield (self.simple_test, "def f( x, (y,z) ): return x,y,z",
-               "f((1,2),(3,4))", ((1,2),3,4))
-        yield (self.simple_test, "def f( x, (y,(z,t)) ): return x,y,z,t",
-               "f(1,(2,(3,4)))", (1,2,3,4))
-        yield (self.simple_test, "def f(((((x,),y),z),t),u): return x,y,z,t,u",
-               "f(((((1,),2),3),4),5)", (1,2,3,4,5))
+        yield (self.error_test, "def f( x, (y,z) ): return x,y,z",
+               SyntaxError)
+        yield (self.error_test, "def f( x, (y,(z,t)) ): return x,y,z,t",
+               SyntaxError)
+        yield (self.error_test, "def f(((((x,),y),z),t),u): return x,y,z,t,u",
+               SyntaxError)
 
     def test_constants(self):
         for c in expressions.constants:
         yield self.st, decl + "x=f(5, b=2, **{'a': 8})", "x", [5, ('a', 8),
                                                                   ('b', 2)]
 
+    def test_kwonly(self):
+        decl = py.code.Source("""
+            def f(a, *, b):
+                return a, b
+        """)
+        decl = str(decl) + '\n'
+        yield self.st, decl + "x=f(1, b=2)", "x", (1, 2)
+
     def test_listmakers(self):
         yield (self.st,
                "l = [(j, i) for j in range(10) for i in range(j)"

pypy/interpreter/pyparser/data/Grammar3.2

 decorators: decorator+
 decorated: decorators (classdef | funcdef)
 funcdef: 'def' NAME parameters ':' suite
-parameters: '(' [varargslist] ')'
-varargslist: ((fpdef ['=' test] ',')*
-              ('*' NAME [',' '**' NAME] | '**' NAME) |
-              fpdef ['=' test] (',' fpdef ['=' test])* [','])
-fpdef: NAME | '(' fplist ')'
-fplist: fpdef (',' fpdef)* [',']
+parameters: '(' [typedargslist] ')'
+typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [','
+       ['*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef]]
+     |  '*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
+tfpdef: NAME [':' test]
+varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [','
+       ['*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef]]
+     |  '*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef)
+vfpdef: NAME
 
 stmt: simple_stmt | compound_stmt
 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE