[pypy-commit] pypy py3k: fix kwonly args with a vararg or kwarg

gutworth noreply at buildbot.pypy.org
Thu Mar 15 01:28:36 CET 2012


Author: Benjamin Peterson <benjamin at python.org>
Branch: py3k
Changeset: r53629:318df86c56e6
Date: 2012-03-14 19:28 -0500
http://bitbucket.org/pypy/pypy/changeset/318df86c56e6/

Log:	fix kwonly args with a vararg or kwarg

diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -27,7 +27,8 @@
         except ValueError:
             pass
         try:
-            return len(self.argnames) + self.kwonlyargnames.index(name)
+            return (len(self.argnames) + self.has_vararg() +
+                    self.kwonlyargnames.index(name))
         except ValueError:
             pass
         return -1
@@ -430,7 +431,7 @@
                             w_key = self.keyword_names_w[i - limit]
                         self.space.setitem(w_kwds, w_key, keywords_w[i])
                 #
-            scope_w[co_argcount + has_vararg] = w_kwds
+            scope_w[co_argcount + co_kwonlyargcount + has_vararg] = w_kwds
         elif num_remainingkwds:
             if co_argcount == 0:
                 raise ArgErrCount(avail, num_kwds,
diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -494,11 +494,11 @@
         assert isinstance(scope, FunctionScope) # Annotator hint.
         if arguments.args:
             self._handle_params(arguments.args, True)
-        if arguments.kwonlyargs:
-            self._handle_params(arguments.kwonlyargs, True)
         if arguments.vararg:
             self.note_symbol(arguments.vararg, SYM_PARAM)
             scope.note_variable_arg(arguments.vararg)
+        if arguments.kwonlyargs:
+            self._handle_params(arguments.kwonlyargs, True)
         if arguments.kwarg:
             self.note_symbol(arguments.kwarg, SYM_PARAM)
             scope.note_keywords_arg(arguments.kwarg)
diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py b/pypy/interpreter/astcompiler/test/test_symtable.py
--- a/pypy/interpreter/astcompiler/test/test_symtable.py
+++ b/pypy/interpreter/astcompiler/test/test_symtable.py
@@ -138,9 +138,11 @@
         assert scp.lookup("x") == symtable.SCOPE_LOCAL
 
     def test_arguments_kwonly(self):
-        scp = self.func_scope("def f(a, *, b): pass")
-        for name in ("a", "b"):
+        scp = self.func_scope("def f(a, *b, c, **d): pass")
+        varnames = ["a", "b", "c", "d"]
+        for name in varnames:
             assert scp.lookup(name) == symtable.SCOPE_LOCAL
+        assert scp.varnames == varnames
 
     def test_function(self):
         scp = self.func_scope("def f(): x = 4")
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -50,13 +50,12 @@
     assert argcount >= 0     # annotator hint
     assert kwonlyargcount >= 0
     argnames = list(code.co_varnames[:argcount])
-    n = argcount + kwonlyargcount
-    kwonlyargs = list(code.co_varnames[argcount:n])
     if code.co_flags & CO_VARARGS:
         varargname = code.co_varnames[argcount]
         argcount += 1
     else:
         varargname = None
+    kwonlyargs = list(code.co_varnames[argcount:argcount + kwonlyargcount])
     if code.co_flags & CO_VARKEYWORDS:
         kwargname = code.co_varnames[argcount]
         argcount += 1
diff --git a/pypy/interpreter/test/test_interpreter.py b/pypy/interpreter/test/test_interpreter.py
--- a/pypy/interpreter/test/test_interpreter.py
+++ b/pypy/interpreter/test/test_interpreter.py
@@ -237,8 +237,17 @@
             '''
         assert self.codetest(code, 'f', []) == os.name
 
+    def test_kwonlyargs_with_kwarg(self):
+        code = """ def f():
+            def g(a, *arg, c, **kw):
+                return [a, arg, c, kw]
+            return g(1, 2, 3, c=4, d=5)
+        """
+        exp = [1, (2, 3), 4, {"d" : 5}]
+        assert self.codetest(code, "f", []) == exp
+
     def test_kwonlyargs_default_parameters(self):
-        code = """ def f(a, b, c=3, *, d=4):
+        code = """ def f(a, b, c=3, d=4):
             return a, b, c, d
         """
         assert self.codetest(code, "f", [1, 2]) == (1, 2, 3, 4)


More information about the pypy-commit mailing list