[pypy-commit] pypy py3.5: Test and fix (and remove the temporary dirty fix which only works if

arigo pypy.commits at gmail.com
Mon Aug 29 04:43:06 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r86674:35fc02e01bf7
Date: 2016-08-29 10:42 +0200
http://bitbucket.org/pypy/pypy/changeset/35fc02e01bf7/

Log:	Test and fix (and remove the temporary dirty fix which only works if
	there is a list object around)

diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1198,7 +1198,7 @@
                 self.settopvalue(self.space.w_None)
 
     @jit.unroll_safe
-    def call_function(self, oparg, w_star=None, w_starstar=None):
+    def call_function(self, oparg, w_starstar=None, has_vararg=False):
         n_arguments = oparg & 0xff
         n_keywords = (oparg>>8) & 0xff
         if n_keywords:
@@ -1210,20 +1210,16 @@
                     break
                 w_value = self.popvalue()
                 w_key = self.popvalue()
-                # temporary (dirty) fix: if star-arg occurs after kwarg,
-                # arg order is reversed on stack
-                from pypy.objspace.std.listobject import W_ListObject
-                if isinstance(w_key, W_ListObject):
-                    w_key_temp = w_key
-                    w_key = w_value
-                    w_value = w_star
-                    w_star = w_key_temp
                 key = self.space.identifier_w(w_key)
                 keywords[n_keywords] = key
                 keywords_w[n_keywords] = w_value
         else:
             keywords = None
             keywords_w = None
+        if has_vararg:
+            w_star = self.popvalue()
+        else:
+            w_star = None
         arguments = self.popvalues(n_arguments)
         args = self.argument_factory(arguments, keywords, keywords_w, w_star,
                                      w_starstar)
@@ -1252,17 +1248,15 @@
             self.call_function(oparg)
 
     def CALL_FUNCTION_VAR(self, oparg, next_instr):
-        w_varargs = self.popvalue()
-        self.call_function(oparg, w_varargs)
+        self.call_function(oparg, has_vararg=True)
 
     def CALL_FUNCTION_KW(self, oparg, next_instr):
         w_varkw = self.popvalue()
-        self.call_function(oparg, None, w_varkw)
+        self.call_function(oparg, w_varkw)
 
     def CALL_FUNCTION_VAR_KW(self, oparg, next_instr):
         w_varkw = self.popvalue()
-        w_varargs = self.popvalue()
-        self.call_function(oparg, w_varargs, w_varkw)
+        self.call_function(oparg, w_varkw, has_vararg=True)
 
     @jit.unroll_safe
     def _make_function(self, oparg, freevars=None):
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
@@ -214,6 +214,15 @@
         assert self.codetest(code, 'g', [12, {}]) ==    ()
         assert self.codetest(code, 'g', [12, {3:1}]) == (3,)
 
+    def test_star_arg_after_keyword_arg(self):
+        code = '''
+            def f(a, b):
+                return a - b
+            def g(a, b):
+                return f(b=b, *(a,))
+        '''
+        assert self.codetest(code, 'g', [40, 2]) == 38
+
     def test_closure(self):
         code = '''
             def f(x, y):


More information about the pypy-commit mailing list