[pypy-commit] pypy py3k: force there to be arguments after *

gutworth noreply at buildbot.pypy.org
Thu Mar 15 02:25:36 CET 2012


Author: Benjamin Peterson <benjamin at python.org>
Branch: py3k
Changeset: r53634:7ed3abb3f0a6
Date: 2012-03-14 20:25 -0500
http://bitbucket.org/pypy/pypy/changeset/7ed3abb3f0a6/

Log:	force there to be arguments after *

diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py
--- a/pypy/interpreter/astcompiler/astbuilder.py
+++ b/pypy/interpreter/astcompiler/astbuilder.py
@@ -552,7 +552,7 @@
             i += 1
         pos = []
         posdefaults = []
-        kwonly = []
+        kwonly = [] if n_kwdonly else None
         kwdefaults = []
         kwarg = None
         kwargann = None
@@ -579,8 +579,9 @@
                 pos.append(self.handle_arg(arg))
                 i += 2
             elif arg_type == tokens.STAR:
-                if i + 1 > child_count:
-                    self.error("named arguments must follow bare *")
+                if i + 1 >= child_count:
+                    self.error("named arguments must follow bare *",
+                               arguments_node)
                 name_node = arguments_node.children[i + 1]
                 keywordonly_args = []
                 if name_node.type == tokens.COMMA:
@@ -612,6 +613,9 @@
                              kwargann, posdefaults, kwdefaults)
 
     def handle_keywordonly_args(self, arguments_node, i, kwonly, kwdefaults):
+        if kwonly is None:
+            self.error("named arguments must follows bare *",
+                       arguments_node.children[i])
         child_count = len(arguments_node.children)
         while i < child_count:
             arg = arguments_node.children[i]
diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py
--- a/pypy/interpreter/astcompiler/test/test_astbuilder.py
+++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py
@@ -541,6 +541,9 @@
         assert fn.args.kwonlyargs[0].arg == "kwarg"
         assert len(fn.args.kw_defaults) == 1
         assert isinstance(fn.args.kw_defaults[0], ast.Num)
+        input = "def f(p1, *, **k1):  pass"
+        exc = py.test.raises(SyntaxError, self.get_ast, input).value
+        assert exc.msg == "named arguments must follows bare *"
 
     def test_function_annotation(self):
         func = self.get_first_stmt("def f() -> X: pass")
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -766,6 +766,19 @@
         assert x is Ellipsis
         """
 
+    def test_keywordonly_syntax_errors(self):
+        cases = ("def f(p, *):\n  pass\n",
+                 "def f(p1, *, p1=100):\n  pass\n",
+                 "def f(p1, *k1, k1=100):\n  pass\n",
+                 "def f(p1, *, k1, k1=100):\n  pass\n",
+                 "def f(p1, *, **k1):\n  pass\n",
+                 "def f(p1, *, k1, **k1):\n  pass\n",
+                 "def f(p1, *, None, **k1):\n  pass\n",
+                 "def f(p, *, (k1, k2), **kw):\n  pass\n")
+        for case in cases:
+            raises(SyntaxError, compile, case, "<test>", "exec")
+
+
 
 class AppTestOptimizer:
 


More information about the pypy-commit mailing list