[pypy-svn] r56939 - in pypy/branch/garden-call-code/pypy: interpreter interpreter/test objspace

pedronis at codespeak.net pedronis at codespeak.net
Sun Aug 3 04:03:50 CEST 2008


Author: pedronis
Date: Sun Aug  3 04:03:48 2008
New Revision: 56939

Modified:
   pypy/branch/garden-call-code/pypy/interpreter/argument.py
   pypy/branch/garden-call-code/pypy/interpreter/baseobjspace.py
   pypy/branch/garden-call-code/pypy/interpreter/eval.py
   pypy/branch/garden-call-code/pypy/interpreter/function.py
   pypy/branch/garden-call-code/pypy/interpreter/gateway.py
   pypy/branch/garden-call-code/pypy/interpreter/pycode.py
   pypy/branch/garden-call-code/pypy/interpreter/test/test_gateway.py
   pypy/branch/garden-call-code/pypy/objspace/descroperation.py
Log:
killed Arguments.popfirst and ArgumentsPrepended introducing call_obj_args and related methods.

a bunch of tests about the blindargs need.

here this speeded up builtin instantiation (bltna1) by 20%, some 10% for user type instantiation too (inst).

some other slow downs/speed ups in the noise (1-5%), one issue is that this overall increased the size of the executable,

some of the next possible changes will prune some stuff though



Modified: pypy/branch/garden-call-code/pypy/interpreter/argument.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/argument.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/argument.py	Sun Aug  3 04:03:48 2008
@@ -6,32 +6,62 @@
 
 class AbstractArguments:
 
-    def parse(self, fnname, signature, defaults_w=[]):
+    def parse_into_scope(self, w_firstarg,
+                         scope_w, fnname, signature, defaults_w=[]):
         """Parse args and kwargs to initialize a frame
         according to the signature of code object.
+        Store the argumentvalues into scope_w.
+        scope_w must be big enough for signature.
         """
+        argnames, varargname, kwargname = signature
+        has_vararg = varargname is not None
+        has_kwarg = kwargname is not None
         try:
-            return self.match_signature(signature, defaults_w)
+            return self._match_signature(w_firstarg,
+                                         scope_w, argnames, has_vararg,
+                                         has_kwarg, defaults_w, 0)
         except ArgErr, e:
             raise OperationError(self.space.w_TypeError,
                                  self.space.wrap(e.getmsg(fnname)))
 
-    def parse_into_scope(self, scope_w, fnname, signature, defaults_w=[]):
-        """Parse args and kwargs to initialize a frame
-        according to the signature of code object.
-        Store the argumentvalues into scope_w.
-        scope_w must be big enough for signature.
+    def _parse(self, w_firstarg, signature, defaults_w, blindargs=0):
+        """Parse args and kwargs according to the signature of a code object,
+        or raise an ArgErr in case of failure.
         """
         argnames, varargname, kwargname = signature
+        scopelen = len(argnames)
         has_vararg = varargname is not None
         has_kwarg = kwargname is not None
+        if has_vararg:
+            scopelen += 1
+        if has_kwarg:
+            scopelen += 1
+        scope_w = [None] * scopelen
+        self._match_signature(w_firstarg, scope_w, argnames, has_vararg, has_kwarg, defaults_w, blindargs)
+        return scope_w    
+
+    def parse(self, fnname, signature, defaults_w=[], blindargs=0):
+        """Parse args and kwargs to initialize a frame
+        according to the signature of code object.
+        """
         try:
-            return self._match_signature(scope_w, argnames, has_vararg,
-                                         has_kwarg, defaults_w, 0, None)
+            return self._parse(None, signature, defaults_w, blindargs)
         except ArgErr, e:
             raise OperationError(self.space.w_TypeError,
                                  self.space.wrap(e.getmsg(fnname)))
 
+    # xxx have only this one
+    def parse_obj(self, w_firstarg,
+                  fnname, signature, defaults_w=[], blindargs=0):
+        """Parse args and kwargs to initialize a frame
+        according to the signature of code object.
+        """
+        try:
+            return self._parse(w_firstarg, signature, defaults_w, blindargs)
+        except ArgErr, e:
+            raise OperationError(self.space.w_TypeError,
+                                 self.space.wrap(e.getmsg(fnname)))        
+
     def frompacked(space, w_args=None, w_kwds=None):
         """Convenience static method to build an Arguments
            from a wrapped sequence and a wrapped dictionary."""
@@ -68,31 +98,11 @@
         return Arguments(space, args_w, kwds_w, w_star, w_starstar)
     fromshape = staticmethod(fromshape)
 
-    def prepend(self, w_firstarg):
-        "Return a new Arguments with a new argument inserted first."
-        return ArgumentsPrepended(self, w_firstarg)
-
-    def popfirst(self):
-        """For optimization only: might return (w_firstarg, args_with_rest),
-        or might just raise IndexError.
-        """
-        raise IndexError
-
     def match_signature(self, signature, defaults_w):
         """Parse args and kwargs according to the signature of a code object,
         or raise an ArgErr in case of failure.
         """
-        argnames, varargname, kwargname = signature
-        scopelen = len(argnames)
-        has_vararg = varargname is not None
-        has_kwarg = kwargname is not None
-        if has_vararg:
-            scopelen += 1
-        if has_kwarg:
-            scopelen += 1
-        scope_w = [None] * scopelen
-        self._match_signature(scope_w, argnames, has_vararg, has_kwarg, defaults_w, 0, None)
-        return scope_w
+        return self._parse(None, signature, defaults_w)
 
     def unmatch_signature(self, signature, data_w):
         """kind of inverse of match_signature"""
@@ -156,7 +166,12 @@
         """
         raise NotImplementedError()
 
-    def _match_signature(self, scope_w, argnames, has_vararg=False, has_kwarg=False, defaults_w=[], blindargs=0, extravarargs=None):
+    def prepend(self, w_firstarg):
+        """ Purely abstract
+        """
+        raise NotImplementedError()    
+
+    def _match_signature(self, w_firstarg, scope_w, argnames, has_vararg=False, has_kwarg=False, defaults_w=[], blindargs=0):
         """ Purely abstract
         """
         raise NotImplementedError()
@@ -164,66 +179,9 @@
     def fixedunpack(self, argcount):
         """ Purely abstract
         """
-        raise NotImplementedError()        
-
-class ArgumentsPrepended(AbstractArguments):
-    def __init__(self, args, w_firstarg):
-        self.space = args.space
-        self.args = args
-        self.w_firstarg = w_firstarg
-        
-    def firstarg(self):
-        "Return the first argument for inspection."
-        return self.w_firstarg
-
-    def popfirst(self):
-        return self.w_firstarg, self.args
-
-    def __repr__(self):
-        return 'ArgumentsPrepended(%r, %r)' % (self.args, self.w_firstarg)
-
-    def has_keywords(self):
-        return self.args.has_keywords()
-
-    def unpack(self):
-        arguments_w, kwds_w = self.args.unpack()
-        return ([self.w_firstarg] + arguments_w), kwds_w
-
-    def fixedunpack(self, argcount):
-        if argcount <= 0:
-            raise ValueError, "too many arguments (%d expected)" % argcount # XXX: Incorrect
-        return [self.w_firstarg] + self.args.fixedunpack(argcount - 1)
-        
-    def _rawshape(self, nextra=0):
-        return self.args._rawshape(nextra + 1)
-
-    def _match_signature(self, scope_w, argnames, has_vararg=False, has_kwarg=False, defaults_w=[], blindargs=0, extravarargs=None):
-        """Parse args and kwargs according to the signature of a code object,
-        or raise an ArgErr in case of failure.
-        Return the number of arguments filled in.
-        """
-        if blindargs < len(argnames):
-            scope_w[blindargs] = self.w_firstarg
-        else:
-            if extravarargs is None:
-                extravarargs = [ self.w_firstarg ]
-            else:
-                extravarargs.append(self.w_firstarg)
-        return self.args._match_signature(scope_w, argnames, has_vararg,
-                                          has_kwarg, defaults_w,
-                                          blindargs + 1, extravarargs)
-    
-    def flatten(self):
-        (shape_cnt, shape_keys, shape_star, shape_stst), data_w = self.args.flatten()
-        data_w.insert(0, self.w_firstarg)
-        return (shape_cnt + 1, shape_keys, shape_star, shape_stst), data_w
+        raise NotImplementedError()
 
-    def num_args(self):
-        return self.args.num_args() + 1
 
-    def num_kwds(self):
-        return self.args.num_kwds()
-    
 class ArgumentsFromValuestack(AbstractArguments):
     """
     Collects the arguments of a function call as stored on a PyFrame
@@ -242,14 +200,11 @@
             return None
         return self.frame.peekvalue(self.nargs - 1)
 
-    def popfirst(self):
-        if self.nargs <= 0:
-            raise IndexError
-        frame = self.frame
-        newnargs = self.nargs-1
-        return (frame.peekvalue(newnargs),
-                ArgumentsFromValuestack(self.space, frame, newnargs))
-
+    def prepend(self, w_firstarg):
+        "Return a new Arguments with a new argument inserted first."
+        args_w = self.frame.peekvalues(self.nargs)
+        return Arguments(self.space, [w_firstarg] + args_w)
+        
     def __repr__(self):
         return 'ArgumentsFromValuestack(%r, %r)' % (self.frame, self.nargs)
 
@@ -276,52 +231,66 @@
     def _rawshape(self, nextra=0):
         return nextra + self.nargs, (), False, False
 
-    def _match_signature(self, scope_w, argnames, has_vararg=False, has_kwarg=False, defaults_w=[], blindargs=0, extravarargs=None):
+    def _match_signature(self, w_firstarg, scope_w, argnames, has_vararg=False, has_kwarg=False, defaults_w=[], blindargs=0):
         """Parse args and kwargs according to the signature of a code object,
         or raise an ArgErr in case of failure.
         Return the number of arguments filled in.
         """
         co_argcount = len(argnames)
-        if blindargs + self.nargs + len(defaults_w) < co_argcount:
+        extravarargs = None
+        input_argcount =  0
+
+        if w_firstarg is not None:
+            blindargs = blindargs or 1
+            upfront = 1
+            if co_argcount > 0:
+                scope_w[0] = w_firstarg
+                input_argcount = 1
+            else:
+                extravarargs = [ w_firstarg ]
+        else:
+            upfront = 0
+
+        avail = upfront + self.nargs
+        
+        if avail + len(defaults_w) < co_argcount:
             raise ArgErrCount(blindargs + self.nargs , 0,
                               (co_argcount, has_vararg, has_kwarg),
-                              defaults_w, co_argcount - blindargs -
-                              self.nargs - len(defaults_w))
-        if blindargs + self.nargs > co_argcount and not has_vararg:
+                              defaults_w, co_argcount - avail - len(defaults_w))
+        if avail > co_argcount and not has_vararg:
             raise ArgErrCount(blindargs + self.nargs, 0,
                               (co_argcount, has_vararg, has_kwarg),
                               defaults_w, 0)
 
-        if blindargs + self.nargs >= co_argcount:
-            for i in range(co_argcount - blindargs):
-                scope_w[i + blindargs] = self.frame.peekvalue(self.nargs - 1 - i)
+        if avail >= co_argcount:
+            for i in range(co_argcount - input_argcount):
+                scope_w[i + input_argcount] = self.frame.peekvalue(self.nargs - 1 - i)
             if has_vararg:
-                if blindargs > co_argcount:
+                if upfront > co_argcount:
+                    assert extravarargs is not None                    
                     stararg_w = extravarargs
                     for i in range(self.nargs):
                         stararg_w.append(self.frame.peekvalue(self.nargs - 1 - i))
                 else:
-                    stararg_w = [None] * (self.nargs + blindargs - co_argcount)
-                    for i in range(co_argcount - blindargs, self.nargs):
-                        stararg_w[i - co_argcount + blindargs] = self.frame.peekvalue(self.nargs - 1 - i)
+                    args_left = co_argcount - upfront                
+                    stararg_w = [None] * (avail - co_argcount)
+                    for i in range(args_left, self.nargs):
+                        stararg_w[i - args_left] = self.frame.peekvalue(self.nargs - 1 - i)
                 scope_w[co_argcount] = self.space.newtuple(stararg_w)
-                co_argcount += 1
         else:
             for i in range(self.nargs):
-                scope_w[i + blindargs] = self.frame.peekvalue(self.nargs - 1 - i)
+                scope_w[i + input_argcount] = self.frame.peekvalue(self.nargs - 1 - i)
             ndefaults = len(defaults_w)
-            missing = co_argcount - self.nargs - blindargs
+            missing = co_argcount - avail
             first_default = ndefaults - missing
             for i in range(missing):
-                scope_w[self.nargs + blindargs + i] = defaults_w[first_default + i]
+                scope_w[avail + i] = defaults_w[first_default + i]
             if has_vararg:
                 scope_w[co_argcount] = self.space.newtuple([])
-                co_argcount += 1
 
         if has_kwarg:
-            scope_w[co_argcount] = self.space.newdict()
-            co_argcount += 1
-        return co_argcount
+            scope_w[co_argcount + has_vararg] = self.space.newdict()
+        return co_argcount + has_vararg + has_kwarg
     
     def flatten(self):
         data_w = [None] * self.nargs
@@ -382,12 +351,12 @@
         "Return a ([w1,w2...], {'kw':w3...}) pair."
         self._unpack()
         return self.arguments_w, self.kwds_w
-    
-    def popfirst(self):
-        self._unpack()
-        return self.arguments_w[0], Arguments(self.space, self.arguments_w[1:],
-            kwds_w = self.kwds_w)
 
+    def prepend(self, w_firstarg):
+        "Return a new Arguments with a new argument inserted first."
+        return Arguments(self.space, [w_firstarg] + self.arguments_w,
+                         self.kwds_w, self.w_stararg, self.w_starstararg)
+            
     def _unpack(self):
         "unpack the *arg and **kwd into w_arguments and kwds_w"
         # --- unpack the * argument now ---
@@ -460,9 +429,8 @@
         
     ###  Parsing for function calls  ###
 
-    def _match_signature(self, scope_w, argnames, has_vararg=False,
-                         has_kwarg=False, defaults_w=[], blindargs=0,
-                         extravarargs=None):
+    def _match_signature(self, w_firstarg, scope_w, argnames, has_vararg=False,
+                         has_kwarg=False, defaults_w=[], blindargs=0):
         """Parse args and kwargs according to the signature of a code object,
         or raise an ArgErr in case of failure.
         Return the number of arguments filled in.
@@ -474,10 +442,24 @@
         #   scope_w = resulting list of wrapped values
         #
         co_argcount = len(argnames) # expected formal arguments, without */**
+        extravarargs = None
+        input_argcount =  0
+
+        if w_firstarg is not None:
+            blindargs = blindargs or 1
+            upfront = 1
+            if co_argcount > 0:
+                scope_w[0] = w_firstarg
+                input_argcount = 1
+            else:
+                extravarargs = [ w_firstarg ]
+        else:
+            upfront = 0
+        
         if self.w_stararg is not None:
             # There is a case where we don't have to unpack() a w_stararg:
             # if it matches exactly a *arg in the signature.
-            if (len(self.arguments_w) + blindargs == co_argcount and
+            if (len(self.arguments_w) + upfront == co_argcount and
                 has_vararg and
                 self.space.is_w(self.space.type(self.w_stararg),
                                 self.space.w_tuple)):
@@ -489,23 +471,25 @@
             self._unpack()
 
         args_w = self.arguments_w
+        num_args = len(args_w)
+
         kwds_w = self.kwds_w
         num_kwds = 0
         if kwds_w is not None:
             num_kwds = len(kwds_w)
-            
-        # put as many positional input arguments into place as available
-        if blindargs >= co_argcount:
-            input_argcount = co_argcount
-        elif len(args_w) + blindargs > co_argcount:
-            for i in range(co_argcount - blindargs):
-                scope_w[i + blindargs] = args_w[i]
-            input_argcount = co_argcount
-            next_arg = co_argcount - blindargs
-        else:
-            for i in range(len(args_w)):
-                scope_w[i + blindargs] = args_w[i]
-            input_argcount = len(args_w) + blindargs
+
+        avail = num_args + upfront
+
+        if input_argcount < co_argcount:
+            # put as many positional input arguments into place as available
+            if avail > co_argcount:
+                take = co_argcount - input_argcount
+            else:
+                take = num_args
+
+            for i in range(take):
+                scope_w[i + input_argcount] = args_w[i]
+            input_argcount += take
 
         # check that no keyword argument conflicts with these
         # note that for this purpose we ignore the first blindargs,
@@ -542,21 +526,21 @@
         # collect extra positional arguments into the *vararg
         if has_vararg:
             if self.w_stararg is None:   # common case
-                args_left = co_argcount - blindargs
+                args_left = co_argcount - upfront
                 if args_left < 0:  # check required by rpython
                     assert extravarargs is not None
                     starargs_w = extravarargs
-                    if len(args_w):
+                    if num_args:
                         starargs_w.extend(args_w)
-                elif len(args_w) > args_left: 
+                elif num_args > args_left:
                     starargs_w = args_w[args_left:]
                 else:
                     starargs_w = []
                 scope_w[co_argcount] = self.space.newtuple(starargs_w)
             else:      # shortcut for the non-unpack() case above
                 scope_w[co_argcount] = self.w_stararg
-        elif len(args_w) + blindargs > co_argcount:
-            raise ArgErrCount(len(args_w) + blindargs, num_kwds,
+        elif avail > co_argcount:
+            raise ArgErrCount(avail, num_kwds,
                               (co_argcount, has_vararg, has_kwarg),
                               defaults_w, 0)
 
@@ -571,7 +555,7 @@
             raise ArgErrUnknownKwds(remainingkwds_w)
 
         if missing:
-            raise ArgErrCount(len(args_w) + blindargs, num_kwds,
+            raise ArgErrCount(avail, num_kwds,
                               (co_argcount, has_vararg, has_kwarg),
                               defaults_w, missing)
 

Modified: pypy/branch/garden-call-code/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/baseobjspace.py	Sun Aug  3 04:03:48 2008
@@ -666,6 +666,12 @@
         return False
 
     def call_obj_args(self, w_callable, w_obj, args):
+        if not self.config.objspace.disable_call_speedhacks:
+            # XXX start of hack for performance            
+            from pypy.interpreter.function import Function        
+            if isinstance(w_callable, Function):
+                return w_callable.call_obj_args(w_obj, args)
+            # XXX end of hack for performance
         return self.call_args(w_callable, args.prepend(w_obj))
 
     def call(self, w_callable, w_args, w_kwds=None):

Modified: pypy/branch/garden-call-code/pypy/interpreter/eval.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/eval.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/eval.py	Sun Aug  3 04:03:48 2008
@@ -57,6 +57,8 @@
         frame.setfastscope(scope_w)
         return frame.run()
 
+    def funcrun_obj(self, func, w_obj, args):
+        return self.funcrun(func, args.prepend(w_obj))
         
     # a performance hack (see gateway.BuiltinCode1/2/3 and pycode.PyCode)
     def fastcall_0(self, space, func):

Modified: pypy/branch/garden-call-code/pypy/interpreter/function.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/function.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/function.py	Sun Aug  3 04:03:48 2008
@@ -33,7 +33,12 @@
         return "<Function %s>" % getattr(self, 'name', '?')
 
     def call_args(self, args):
-        return self.code.funcrun(self, args) # delegate activation to code
+        # delegate activation to code        
+        return self.code.funcrun(self, args)
+
+    def call_obj_args(self, w_obj, args):
+        # delegate activation to code
+        return self.code.funcrun_obj(self, w_obj, args)
 
     def getcode(self):
         return self.code
@@ -98,9 +103,8 @@
                                        frame.peekvalue(1),
                                        frame.peekvalue(0))
         stkargs = frame.make_arguments(nargs)
-        args = stkargs.prepend(w_obj)
         try:
-            return self.call_args(args) # xxx Function.call_obj_args
+            return self.call_obj_args(w_obj, stkargs)
         finally:
             if isinstance(stkargs, ArgumentsFromValuestack):
                 stkargs.frame = None

Modified: pypy/branch/garden-call-code/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/gateway.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/gateway.py	Sun Aug  3 04:03:48 2008
@@ -479,9 +479,13 @@
         return space.wrap(self.docstring)
 
     def funcrun(self, func, args):
+        return BuiltinCode.funcrun_obj(self, func, None, args)
+
+    def funcrun_obj(self, func, w_obj, args):
         space = func.space
         activation = self.activation
-        scope_w = args.parse(func.name, self.sig, func.defs_w)
+        scope_w = args.parse_obj(w_obj, func.name, self.sig,
+                                 func.defs_w, self.minargs)
         try:
             w_result = activation._run(space, scope_w)
         except KeyboardInterrupt: 
@@ -495,6 +499,8 @@
             raise OperationError(space.w_RuntimeError, 
                                  space.wrap("internal error: " + str(e)))
         except DescrMismatch, e:
+            if w_obj is not None:
+                args = args.prepend(w_obj)
             return scope_w[0].descr_call_mismatch(space,
                                                   self.descrmismatch_op,
                                                   self.descr_reqcls,
@@ -531,32 +537,27 @@
 
 class BuiltinCodePassThroughArguments1(BuiltinCode):
 
-    def funcrun(self, func, args):
+    def funcrun_obj(self, func, w_obj, args):
         space = func.space
         try:
-            w_obj, newargs = args.popfirst()
-        except IndexError:
-            return BuiltinCode.funcrun(self, func, args)
-        else:
-            try:
-                w_result = self.func__args__(space, w_obj, newargs)
-            except KeyboardInterrupt: 
-                raise OperationError(space.w_KeyboardInterrupt, space.w_None) 
-            except MemoryError: 
-                raise OperationError(space.w_MemoryError, space.w_None)
-            except NotImplementedError, e:
-                raise
-            except RuntimeError, e: 
-                raise OperationError(space.w_RuntimeError, 
-                                     space.wrap("internal error: " + str(e))) 
-            except DescrMismatch, e:
-                return args.firstarg().descr_call_mismatch(space,
-                                                      self.descrmismatch_op,
-                                                      self.descr_reqcls,
-                                                      args)
-            if w_result is None:
-                w_result = space.w_None
-            return w_result
+            w_result = self.func__args__(space, w_obj, args)
+        except KeyboardInterrupt: 
+            raise OperationError(space.w_KeyboardInterrupt, space.w_None) 
+        except MemoryError: 
+            raise OperationError(space.w_MemoryError, space.w_None)
+        except NotImplementedError, e:
+            raise
+        except RuntimeError, e: 
+            raise OperationError(space.w_RuntimeError, 
+                                 space.wrap("internal error: " + str(e))) 
+        except DescrMismatch, e:
+            return args.firstarg().descr_call_mismatch(space,
+                                                  self.descrmismatch_op,
+                                                  self.descr_reqcls,
+                                                  args.prepend(w_obj))
+        if w_result is None:
+            w_result = space.w_None
+        return w_result
 
 class BuiltinCode0(BuiltinCode):
     fast_natural_arity = 0

Modified: pypy/branch/garden-call-code/pypy/interpreter/pycode.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/pycode.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/pycode.py	Sun Aug  3 04:03:48 2008
@@ -212,7 +212,19 @@
                                   func.closure)
         sig = self._signature
         # speed hack
-        args_matched = args.parse_into_scope(frame.fastlocals_w, func.name,
+        args_matched = args.parse_into_scope(None, frame.fastlocals_w,
+                                             func.name,
+                                             sig, func.defs_w)
+        frame.init_cells()
+        return frame.run()
+
+    def funcrun_obj(self, func, w_obj, args):
+        frame = self.space.createframe(self, func.w_func_globals,
+                                  func.closure)
+        sig = self._signature
+        # speed hack
+        args_matched = args.parse_into_scope(w_obj, frame.fastlocals_w,
+                                             func.name,
                                              sig, func.defs_w)
         frame.init_cells()
         return frame.run()

Modified: pypy/branch/garden-call-code/pypy/interpreter/test/test_gateway.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/test/test_gateway.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/test/test_gateway.py	Sun Aug  3 04:03:48 2008
@@ -495,22 +495,19 @@
 
         w_self = space.wrap('self')
 
-        args0 = argument.Arguments(space, [space.wrap(0)])
-        args = args0.prepend(w_self)
-
-        w_res = space.call_args(w_g, args)
-        assert space.is_true(space.eq(w_res, space.wrap(('g', 'self', 0))))
-        
-        # white-box check for opt
-        assert called[0] is args0
-        called = []
-
         args3 = argument.Arguments(space, [space.wrap(3)])
         w_res = space.call_obj_args(w_g, w_self, args3)
         assert space.is_true(space.eq(w_res, space.wrap(('g', 'self', 3))))
         # white-box check for opt
         assert called[0] is args3
 
+        # no opt in this case
+        args0 = argument.Arguments(space, [space.wrap(0)])
+        args = args0.prepend(w_self)
+
+        w_res = space.call_args(w_g, args)
+        assert space.is_true(space.eq(w_res, space.wrap(('g', 'self', 0))))
+        
     def test_plain(self):
         space = self.space
 
@@ -538,3 +535,46 @@
         args3 = argument.Arguments(space, [space.wrap(3)])
         w_res = space.call_obj_args(w_g, w_self, args3)
         assert space.is_true(space.eq(w_res, space.wrap(('g', 'self', 3))))
+
+
+class AppTestKeywordsToBuiltinSanity(object):
+
+    def test_type(self):
+        class X(object):
+            def __init__(self, **kw):
+                pass
+        clash = type.__call__.func_code.co_varnames[0]
+
+        X(**{clash: 33})
+        type.__call__(X, **{clash: 33})
+
+    def test_object_new(self):
+        class X(object):
+            def __init__(self, **kw):
+                pass
+        clash = object.__new__.func_code.co_varnames[0]
+
+        X(**{clash: 33})
+        object.__new__(X, **{clash: 33})
+
+
+    def test_dict_new(self):
+        clash = dict.__new__.func_code.co_varnames[0]
+
+        dict(**{clash: 33})
+        dict.__new__(dict, **{clash: 33})        
+
+    def test_dict_init(self):
+        d = {}
+        clash = dict.__init__.func_code.co_varnames[0]
+
+        d.__init__(**{clash: 33})
+        dict.__init__(d, **{clash: 33})
+
+    def test_dict_update(self):
+        d = {}
+        clash = dict.update.func_code.co_varnames[0]
+
+        d.update(**{clash: 33})
+        dict.update(d, **{clash: 33})        
+        

Modified: pypy/branch/garden-call-code/pypy/objspace/descroperation.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/objspace/descroperation.py	(original)
+++ pypy/branch/garden-call-code/pypy/objspace/descroperation.py	Sun Aug  3 04:03:48 2008
@@ -75,7 +75,7 @@
         descr = space.interpclass_w(w_descr)
         # a special case for performance and to avoid infinite recursion
         if type(descr) is Function:
-            return descr.call_args(args.prepend(w_obj)) # xxx Function.call_obj_args
+            return descr.call_obj_args(w_obj, args)
         else:
             w_impl = space.get(w_descr, w_obj)
             return space.call_args(w_impl, args)



More information about the Pypy-commit mailing list