[pypy-svn] r5300 - in pypy/trunk/src/pypy: interpreter objspace objspace/flow objspace/std

arigo at codespeak.net arigo at codespeak.net
Fri Jun 25 17:00:10 CEST 2004


Author: arigo
Date: Fri Jun 25 17:00:08 2004
New Revision: 5300

Added:
   pypy/trunk/src/pypy/interpreter/argument.py   (contents, props changed)
Modified:
   pypy/trunk/src/pypy/interpreter/baseobjspace.py
   pypy/trunk/src/pypy/interpreter/function.py
   pypy/trunk/src/pypy/interpreter/pyopcode.py
   pypy/trunk/src/pypy/objspace/descroperation.py
   pypy/trunk/src/pypy/objspace/flow/objspace.py
   pypy/trunk/src/pypy/objspace/std/cpythonobject.py
   pypy/trunk/src/pypy/objspace/std/typeobject.py
   pypy/trunk/src/pypy/objspace/trivial.py
Log:
First steps in the direction of a cleaner argument handling scheme.
There is now a class pypy.interpreter.argument.Arguments that holds the 
arguments of a Python call.  All operations on them (joining & parsing) are 
now there.  The official calling interface is now

  space.call_args(w_callable, args)

with space.call_function still available as a thin helper (but no keyword 
arguments in space.call_function() please).  We should scrap space.call() now.

Work in progress: the app2interp gateways should use arguments of this kind 
instead of interp-level */** arguments; the multimethods as well.



Added: pypy/trunk/src/pypy/interpreter/argument.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/interpreter/argument.py	Fri Jun 25 17:00:08 2004
@@ -0,0 +1,191 @@
+"""
+Arguments objects.
+"""
+
+from pypy.interpreter.error import OperationError
+
+
+class Arguments:
+    """
+    Collects the arguments of a function call.
+    
+    Instances should be considered immutable.
+    """
+
+    ###  Construction  ###
+
+    def __init__(self, space, args_w=[], kwds_w={}):
+        self.space = space
+        self.args_w = args_w
+        self.kwds_w = kwds_w
+
+    def frompacked(space, w_args=None, w_kwds=None):
+        """Static method to build an Arguments
+        from a wrapped sequence and optionally a wrapped dictionary.
+        """
+        if w_args is None:
+            args_w = []
+        else:
+            args_w = space.unpackiterable(w_args)
+        if w_kwds is None:
+            return Arguments(space, args_w)
+        # maybe we could allow general mappings?
+        if not space.is_true(space.isinstance(w_kwds, space.w_dict)):
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("the keywords must be "
+                                            "a dictionary"))
+        kwds_w = {}
+        for w_key in space.unpackiterable(w_kwds):
+            key = space.unwrap(w_key)
+            if not isinstance(key, str):
+                raise OperationError(space.w_TypeError,
+                                     space.wrap("keywords must be strings"))
+            kwds_w[key] = space.getitem(w_kwds, w_key)
+        return Arguments(space, args_w, kwds_w)
+    frompacked = staticmethod(frompacked)
+
+    ###  Manipulation  ###
+
+    def prepend(self, w_firstarg):
+        "Return a new Arguments with a new argument inserted first."
+        return Arguments(self.space, [w_firstarg] + self.args_w, self.kwds_w)
+
+    def join(self, other):
+        "Return a new Arguments combining the content of two Arguments."
+        args_w = self.args_w + other.args_w
+        kwds_w = self.kwds_w.copy()
+        for key, w_value in other.kwds_w.items():
+            if key in kwds_w:
+                raise OperationError(self.space.w_TypeError,
+                                     self.space.wrap("got multiple values for "
+                                                     "keyword argument '%s'" %
+                                                     key))
+            kwds_w[key] = w_value
+        return Arguments(self.space, args_w, kwds_w)
+
+    def pack(self):
+        "Return a (wrapped tuple, wrapped dictionary)."
+        space = self.space
+        w_args = space.newtuple(self.args_w)
+        w_kwds = space.newdict([(space.wrap(key), w_value)
+                                for key, w_value in self.kwds_w.items()])
+        return w_args, w_kwds
+
+    ###  Parsing for function calls  ###
+
+    def parse(self, fnname, signature, defaults_w=[]):
+        """Parse args and kwargs to initialize a frame
+        according to the signature of code object.
+        """
+        space = self.space
+        args_w = self.args_w
+        kwds_w = self.kwds_w
+        argnames, varargname, kwargname = signature
+        #
+        #   args_w = list of the normal actual parameters, wrapped
+        #   kwds_w = real dictionary {'keyword': wrapped parameter}
+        #   argnames = list of formal parameter names
+        #   scope_w = resulting list of wrapped values
+        #
+        # We try to give error messages following CPython's, which are
+        # very informative.
+        #
+        co_argcount = len(argnames) # expected formal arguments, without */**
+
+        # put as many positional input arguments into place as available
+        scope_w = args_w[:co_argcount]
+        input_argcount = len(scope_w)
+
+        # check that no keyword argument conflicts with these
+        if kwds_w:
+            for name in argnames[:input_argcount]:
+                if name in kwds_w:
+                    self.raise_argerr_multiple_values(fnname, name)
+
+        remainingkwds_w = kwds_w.copy()
+        if input_argcount < co_argcount:
+            # not enough args, fill in kwargs or defaults if exists
+            def_first = co_argcount - len(defaults_w)
+            for i in range(input_argcount, co_argcount):
+                name = argnames[i]
+                if name in remainingkwds_w:
+                    scope_w.append(remainingkwds_w[name])
+                    del remainingkwds_w[name]
+                elif i >= def_first:
+                    scope_w.append(defaults_w[i-def_first])
+                else:
+                    self.raise_argerr(fnname, signature, defaults_w, False)
+                    
+        # collect extra positional arguments into the *vararg
+        if varargname is not None:
+            scope_w.append(space.newtuple(args_w[co_argcount:]))
+        elif len(args_w) > co_argcount:
+            self.raise_argerr(fnname, signature, defaults_w, True)
+
+        # collect extra keyword arguments into the **kwarg
+        if kwargname is not None:
+            w_kwds = space.newdict([(space.wrap(key), w_value)
+                                    for key, w_value in remainingkwds_w.items()])
+            scope_w.append(w_kwds)
+        elif remainingkwds_w:
+            self.raise_argerr_unknown_kwds(fnname, remainingkwds_w)
+        return scope_w
+
+    # helper functions to build error message for the above
+
+    def raise_argerr(self, fnname, signature, defaults_w, too_many):
+        argnames, varargname, kwargname = signature
+        nargs = len(self.args_w)
+        n = len(argnames)
+        if n == 0:
+            if kwargname is not None:
+                msg2 = "non-keyword "
+            else:
+                msg2 = ""
+                nargs += len(self.kwds_w)
+            msg = "%s() takes no %sargument (%d given)" % (
+                fnname, 
+                msg2,
+                nargs)
+        else:
+            defcount = len(defaults_w)
+            if defcount == 0:
+                msg1 = "exactly"
+            elif too_many:
+                msg1 = "at most"
+            else:
+                msg1 = "at least"
+                n -= defcount
+            if kwargname is not None:
+                msg2 = "non-keyword "
+            else:
+                msg2 = ""
+            if n == 1:
+                plural = ""
+            else:
+                plural = "s"
+            msg = "%s() takes %s %d %sargument%s (%d given)" % (
+                fnname,
+                msg1,
+                n,
+                msg2,
+                plural,
+                nargs)
+        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
+
+    def raise_argerr_multiple_values(self, fnname, argname):
+        msg = "%s() got multiple values for keyword argument %s" % (
+            fnname,
+            argname)
+        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
+
+    def raise_argerr_unknown_kwds(self, fnname, kwds_w):
+        if len(kwds_w) == 1:
+            msg = "%s() got an unexpected keyword argument '%s'" % (
+                fnname,
+                kwds_w.keys()[0])
+        else:
+            msg = "%s() got %d unexpected keyword arguments" % (
+                fnname,
+                len(kwds_w))
+        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))

Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/trunk/src/pypy/interpreter/baseobjspace.py	Fri Jun 25 17:00:08 2004
@@ -1,6 +1,7 @@
 from pypy.interpreter.executioncontext import ExecutionContext
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.miscutils import getthreadlocals
+from pypy.interpreter.argument import Arguments
 
 __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable']
 
@@ -182,39 +183,17 @@
                 check_list.extend(exclst)
         return False
 
-    def unpackdictionary(self, w_mapping):
-        "Turns a wrapped dictionary into a {'string': w_value} dict."
-        if not self.is_mapping(w_mapping):
-            raise OperationError(self.w_TypeError,
-                                 self.wrap("the keywords must be a dictionary"))
-        result = {}
-        for w_key in self.unpackiterable(w_mapping):
-            key = self.unwrap(w_key)
-            if not isinstance(key, str):
-                raise OperationError(self.w_TypeError,
-                                     self.wrap("keywords must be strings"))
-            result[key] = self.getitem(w_mapping, w_key)
-        return result
-
-    def is_mapping(self, w_mapping):
-        # XXX extend to detect general mappings
-        return self.is_true(self.isinstance(w_mapping, self.w_dict))
-
     def call(self, w_callable, w_args, w_kwds=None):
-        "Deprecated.  Use call_function() instead."
-        args_w = self.unpacktuple(w_args)
-        if w_kwds is None:
-            return self.call_function(w_callable, *args_w)
-        else:
-            kwds_w = self.unpackdictionary(w_kwds)
-            return self.call_function(w_callable, *args_w, **kwds_w)
+        args = Arguments.frompacked(self, w_args, w_kwds)
+        return self.call_args(w_callable, args)
 
-##    def call_function(self, w_func, *args_w, **kw_w):
-##        implemented by subclasses
+    def call_function(self, w_func, *args_w):
+        args = Arguments(self, list(args_w))
+        return self.call_args(w_func, args)
 
-    def call_method(self, w_obj, methname, *arg_w, **kw_w):
+    def call_method(self, w_obj, methname, *arg_w):
         w_meth = self.getattr(w_obj, self.wrap(methname))
-        return self.call_function(w_meth, *arg_w, **kw_w)
+        return self.call_function(w_meth, *arg_w)
 
     def isinstance(self, w_obj, w_type):
         w_objtype = self.type(w_obj)
@@ -377,4 +356,4 @@
 #      newstring([w_1, w_2,...]) -> w_string from ascii numbers (bytes)
 # newdict([(w_key,w_value),...]) -> w_dict
 #newslice(w_start,w_stop,w_step) -> w_slice (any argument may be a real None)
-#   call_function(w_obj,*args_w,**kwds_w)
+#   call_args(w_obj,Arguments()) -> w_result

Modified: pypy/trunk/src/pypy/interpreter/function.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/function.py	(original)
+++ pypy/trunk/src/pypy/interpreter/function.py	Fri Jun 25 17:00:08 2004
@@ -8,6 +8,7 @@
 
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.argument import Arguments
 
 class Function(Wrappable):
     """A function is a code object captured with some environment:
@@ -24,128 +25,13 @@
         self.defs_w    = defs_w     # list of w_default's
         self.w_func_dict = space.newdict([])
 
-    def call_function(self, *args_w, **kwds_w):
-        scope_w = self.parse_args(list(args_w), kwds_w)
+    def call_args(self, args):
+        scope_w = args.parse(self.name, self.code.signature(), self.defs_w)
         frame = self.code.create_frame(self.space, self.w_func_globals,
                                             self.closure)
         frame.setfastscope(scope_w)
         return frame.run()
 
-    def parse_args(self, args_w, kwds_w):
-        """ parse args and kwargs to initialize the frame.
-        """
-        space = self.space
-        signature = self.code.signature()
-        argnames, varargname, kwargname = signature
-        #
-        #   args_w = list of the normal actual parameters, wrapped
-        #   kwds_w = real dictionary {'keyword': wrapped parameter}
-        #   argnames = list of formal parameter names
-        #   scope_w = resulting list of wrapped values
-        #
-        # We try to give error messages following CPython's, which are
-        # very informative.
-        #
-        co_argcount = len(argnames) # expected formal arguments, without */**
-
-        # put as many positional input arguments into place as available
-        scope_w = args_w[:co_argcount]
-        input_argcount = len(scope_w)
-
-        # check that no keyword argument conflicts with these
-        if kwds_w:
-            for name in argnames[:input_argcount]:
-                if name in kwds_w:
-                    self.raise_argerr_multiple_values(name)
-
-        remainingkwds_w = kwds_w.copy()
-        if input_argcount < co_argcount:
-            # not enough args, fill in kwargs or defaults if exists
-            def_first = co_argcount - len(self.defs_w)
-            for i in range(input_argcount, co_argcount):
-                name = argnames[i]
-                if name in remainingkwds_w:
-                    scope_w.append(remainingkwds_w[name])
-                    del remainingkwds_w[name]
-                elif i >= def_first:
-                    scope_w.append(self.defs_w[i-def_first])
-                else:
-                    self.raise_argerr(args_w, kwds_w, False)
-                    
-        # collect extra positional arguments into the *vararg
-        if varargname is not None:
-            scope_w.append(space.newtuple(args_w[co_argcount:]))
-        elif len(args_w) > co_argcount:
-            self.raise_argerr(args_w, kwds_w, True)
-
-        # collect extra keyword arguments into the **kwarg
-        if kwargname is not None:
-            w_kwds = space.newdict([(space.wrap(key), w_value)
-                                    for key, w_value in remainingkwds_w.items()])
-            scope_w.append(w_kwds)
-        elif remainingkwds_w:
-            self.raise_argerr_unknown_kwds(remainingkwds_w)
-        return scope_w
-
-    # helper functions to build error message for the above
-
-    def raise_argerr(self, args_w, kwds_w, too_many):
-        argnames, varargname, kwargname = self.code.signature()
-        nargs = len(args_w)
-        n = len(argnames)
-        if n == 0:
-            if kwargname is not None:
-                msg2 = "non-keyword "
-            else:
-                msg2 = ""
-                nargs += len(kwds_w)
-            msg = "%s() takes no %sargument (%d given)" % (
-                self.name, 
-                msg2,
-                nargs)
-        else:
-            defcount = len(self.defs_w)
-            if defcount == 0:
-                msg1 = "exactly"
-            elif too_many:
-                msg1 = "at most"
-            else:
-                msg1 = "at least"
-                n -= defcount
-            if kwargname is not None:
-                msg2 = "non-keyword "
-            else:
-                msg2 = ""
-            if n == 1:
-                plural = ""
-            else:
-                plural = "s"
-            msg = "%s() takes %s %d %sargument%s (%d given)" % (
-                self.name,
-                msg1,
-                n,
-                msg2,
-                plural,
-                nargs)
-        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
-
-    def raise_argerr_multiple_values(self, argname):
-        msg = "%s() got multiple values for keyword argument %s" % (
-            self.name,
-            argname)
-        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
-
-    def raise_argerr_unknown_kwds(self, kwds_w):
-        if len(kwds_w) == 1:
-            msg = "%s() got an unexpected keyword argument '%s'" % (
-                self.name,
-                kwds_w.keys()[0])
-        else:
-            msg = "%s() got %d unexpected keyword arguments" % (
-                self.name,
-                len(kwds_w))
-        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
-
     def getdict(self):
         return self.w_func_dict
 
@@ -166,7 +52,9 @@
             return wrap(Method(space, wrap(self), None, w_cls))
 
     def descr_function_call(self, *args_w, **kwds_w):
-        return self.call_function(*args_w, **kwds_w)
+        # XXX the Gateway interface should not use interp-level */**
+        # XXX arguments -- conflict with 'self'!
+        return self.call_args(Arguments(self.space, list(args_w), kwds_w))
 
     def fget_func_defaults(space, w_self):
         self = space.unwrap(w_self)
@@ -199,25 +87,25 @@
         self.w_instance = w_instance   # or None
         self.w_class = w_class
 
-    def call_function(self, *args_w, **kwds_w):
+    def call_args(self, args):
         if self.w_instance is not None:
             # bound method
-            return self.space.call_function(self.w_function, self.w_instance,
-                                            *args_w, **kwds_w)
+            args = args.prepend(self.w_instance)
         else:
             # unbound method
-            if (len(args_w) >= 1 and self.space.is_true(
-                    self.space.isinstance(args_w[0], self.w_class))):
+            if (len(args.args_w) >= 1 and self.space.is_true(
+                    self.space.isinstance(args.args_w[0], self.w_class))):
                 pass  # ok
             else:
                 msg = ("unbound method must be called with "
                        "instance as first argument")     # XXX fix error msg
                 raise OperationError(self.space.w_TypeError,
                                      self.space.wrap(msg))
-            return self.space.call_function(self.w_function, *args_w, **kwds_w)
+        return self.space.call_args(self.w_function, args)
 
     def descr_method_call(self, *args_w, **kwds_w):
-        return self.call_function(*args_w, **kwds_w)
+        # XXX same as descr_function_call()
+        return self.call_args(Arguments(self.space, list(args_w), kwds_w))
 
 class StaticMethod(Wrappable):
     """A static method.  Note that there is one class staticmethod at

Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyopcode.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pyopcode.py	Fri Jun 25 17:00:08 2004
@@ -9,6 +9,7 @@
 from pypy.interpreter import gateway, function
 from pypy.interpreter import pyframe, pytraceback
 from pypy.interpreter.miscutils import InitializedClass
+from pypy.interpreter.argument import Arguments
 
 
 class unaryoperation:
@@ -680,13 +681,9 @@
         block = pyframe.FinallyBlock(f, f.next_instr + offsettoend)
         f.blockstack.push(block)
 
-    def call_function_extra(f, oparg, with_varargs, with_varkw):
+    def CALL_FUNCTION(f, oparg, extra_args=None):
         n_arguments = oparg & 0xff
         n_keywords = (oparg>>8) & 0xff
-        if with_varkw:
-            w_varkw = f.valuestack.pop()
-        if with_varargs:
-            w_varargs = f.valuestack.pop()
         keywords = {}
         for i in range(n_keywords):
             w_value = f.valuestack.pop()
@@ -695,31 +692,28 @@
             keywords[key] = w_value
         arguments = [f.valuestack.pop() for i in range(n_arguments)]
         arguments.reverse()
+        args = Arguments(f.space, arguments, keywords)
+        if extra_args:
+            args = args.join(extra_args)
         w_function  = f.valuestack.pop()
-        if with_varargs:    # add the arguments provided by the *args syntax
-            arguments += tuple(f.space.unpackiterable(w_varargs))
-        if with_varkw:      # add the arguments provided by the **kwds syntax
-            kwds_w = f.space.unpackdictionary(w_varkw)
-            for key, w_value in kwds_w.items():
-                if key in keywords:
-                    raise OperationError(f.space.w_TypeError,
-                            f.space.wrap("got multiple values for "
-                                         "keyword argument '%s'" % key))
-                keywords[key] = w_value
-        w_result = f.space.call_function(w_function, *arguments, **keywords)
+        w_result = f.space.call_args(w_function, args)
         f.valuestack.push(w_result)
 
-    def CALL_FUNCTION(f, oparg):
-        f.call_function_extra(oparg, False, False)
-
     def CALL_FUNCTION_VAR(f, oparg):
-        f.call_function_extra(oparg, True,  False)
+        w_varargs = f.valuestack.pop()
+        extra_args = Arguments.frompacked(f.space, w_varargs)
+        f.CALL_FUNCTION(oparg, extra_args)
 
     def CALL_FUNCTION_KW(f, oparg):
-        f.call_function_extra(oparg, False, True)
+        w_varkw = f.valuestack.pop()
+        extra_args = Arguments.frompacked(f.space, w_kwds=w_varkw)
+        f.CALL_FUNCTION(oparg, extra_args)
 
     def CALL_FUNCTION_VAR_KW(f, oparg):
-        f.call_function_extra(oparg, True,  True)
+        w_varkw = f.valuestack.pop()
+        w_varargs = f.valuestack.pop()
+        extra_args = Arguments.frompacked(f.space, w_varargs, w_varkw)
+        f.CALL_FUNCTION(oparg, extra_args)
 
     def MAKE_FUNCTION(f, numdefaults):
         w_codeobj = f.valuestack.pop()

Modified: pypy/trunk/src/pypy/objspace/descroperation.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/descroperation.py	(original)
+++ pypy/trunk/src/pypy/objspace/descroperation.py	Fri Jun 25 17:00:08 2004
@@ -2,6 +2,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import ObjSpace
 from pypy.interpreter.function import Function
+from pypy.interpreter.argument import Arguments
 
 class Object:
     def descr__getattribute__(space, w_obj, w_name):
@@ -58,26 +59,18 @@
     def is_data_descr(space, w_obj):
         return space.lookup(w_obj, '__set__') is not None
 
-##    def get_and_call(space, w_descr, w_obj, w_args, w_kwargs):
-##        descr = space.unwrap_builtin(w_descr)
-##        if isinstance(descr, Function):
-##            # special-case Functions to avoid infinite recursion
-##            args_w = space.unpacktuple(w_args)
-##            args_w = [w_obj] + args_w
-##            w_args = space.newtuple(args_w)
-##            return descr.call(w_args, w_kwargs)
-##        else:
-##            w_impl = space.get(w_descr, w_obj)
-##            return space.call(w_impl, w_args, w_kwargs)
-
-    def get_and_call_function(space, w_descr, w_obj, *args_w, **kwargs_w):
+    def get_and_call_args(space, w_descr, w_obj, args):
         descr = space.unwrap_builtin(w_descr)
         if isinstance(descr, Function):
             # special-case Functions to avoid infinite recursion
-            return descr.call_function(w_obj, *args_w, **kwargs_w)
+            return descr.call_args(args.prepend(w_obj))
         else:
             w_impl = space.get(w_descr, w_obj)
-            return space.call_function(w_impl, *args_w, **kwargs_w)
+            return space.call_args(w_impl, args)
+
+    def get_and_call_function(space, w_descr, w_obj, *args_w):
+        args = Arguments(space, list(args_w))
+        return space.get_and_call_args(w_descr, w_obj, args)
 
     def unwrap_builtin(self, w_obj):
         return w_obj    # hook for hack by TrivialObjSpace
@@ -90,12 +83,12 @@
 ##                              space.wrap('object %r is not callable' % (w_obj,)))
 ##        return space.get_and_call(w_descr, w_obj, w_args, w_kwargs)
 
-    def call_function(space, w_obj, *args_w, **kwds_w):
+    def call_args(space, w_obj, args):
         w_descr = space.lookup(w_obj, '__call__')
         if w_descr is None:
             raise OperationError(space.w_TypeError, 
                                  space.wrap('object %r is not callable' % (w_obj,)))
-        return space.get_and_call_function(w_descr, w_obj, *args_w, **kwds_w)
+        return space.get_and_call_args(w_descr, w_obj, args)
 
     def get(space,w_descr,w_obj,w_type=None):
         w_get = space.lookup(w_descr,'__get__')

Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/objspace.py	(original)
+++ pypy/trunk/src/pypy/objspace/flow/objspace.py	Fri Jun 25 17:00:08 2004
@@ -147,9 +147,12 @@
         else:
             return w_item
 
-    def call_function(self, w_callable, *args_w, **kwds_w):
-        assert not kwds_w, "don't know yet about keyword arguments"
-        return self.do_operation('simple_call', w_callable, *args_w)
+    def call_args(self, w_callable, args):
+        if args.kwds_w:
+            w_args, w_kwds = args.pack()
+            return self.do_operation('call', w_callable, w_args, w_kwds)
+        else:
+            return self.do_operation('simple_call', w_callable, *args.args_w)
 
 # ______________________________________________________________________
 

Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/cpythonobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py	Fri Jun 25 17:00:08 2004
@@ -16,16 +16,16 @@
         self.space = space
         self.cpyfunc = cpyfunc
 
-    def call_function(self, *args_w, **kwds_w):
+    def call_args(self, args):
         space = self.space
         try:
-            args = [space.unwrap(w_arg) for w_arg in args_w]
-            kwds = dict([(key, space.unwrap(w_value))
-                         for key, w_value in kwds_w.items()])
+            unwrappedargs = [space.unwrap(w_arg) for w_arg in args.args_w]
+            unwrappedkwds = dict([(key, space.unwrap(w_value))
+                                  for key, w_value in args.kwds_w.items()])
         except UnwrapError, e:
             raise UnwrapError('calling %s: %s' % (self.cpyfunc, e))
         try:
-            result = apply(self.cpyfunc, args, kwds)
+            result = apply(self.cpyfunc, unwrappedargs, unwrappedkwds)
         except:
             wrap_exception(space)
         return space.wrap(result)

Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/typeobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/typeobject.py	Fri Jun 25 17:00:08 2004
@@ -1,6 +1,7 @@
 from pypy.objspace.std.objspace import *
 from pypy.interpreter.function import Function, StaticMethod
 from pypy.interpreter.typedef import default_dict_descr
+from pypy.interpreter.argument import Arguments
 from pypy.objspace.std.stdtypedef import issubtypedef
 from pypy.objspace.std.objecttype import object_typedef
 
@@ -91,19 +92,18 @@
 
 
 def call__Type(space, w_type, w_args, w_kwds):
-    args_w = space.unpacktuple(w_args)
-    kwds_w = space.unpackdictionary(w_kwds)
+    args = Arguments.frompacked(space, w_args, w_kwds)
     # special case for type(x)
     if (space.is_true(space.is_(w_type, space.w_type)) and
-        len(args_w) == 1 and not kwds_w):
-        return space.type(args_w[0])
+        len(args.args_w) == 1 and not args.kwds_w):
+        return space.type(args.args_w[0])
     # invoke the __new__ of the type
     w_newfunc = space.getattr(w_type, space.wrap('__new__'))
-    w_newobject = space.call_function(w_newfunc, w_type, *args_w, **kwds_w)
+    w_newobject = space.call_args(w_newfunc, args.prepend(w_type))
     # maybe invoke the __init__ of the type
     if space.is_true(space.isinstance(w_newobject, w_type)):
         w_descr = space.lookup(w_newobject, '__init__')
-        space.get_and_call_function(w_descr, w_newobject, *args_w, **kwds_w)
+        space.get_and_call_args(w_descr, w_newobject, args)
     return w_newobject
 
 def issubtype__Type_Type(space, w_type1, w_type2):

Modified: pypy/trunk/src/pypy/objspace/trivial.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/trivial.py	(original)
+++ pypy/trunk/src/pypy/objspace/trivial.py	Fri Jun 25 17:00:08 2004
@@ -479,29 +479,15 @@
                     return cls.__dict__[name]
             return None
 
-##    def get_and_call(self, w_descr, w_obj, w_args, w_kwargs):
-##        if isinstance(w_descr, CPyWrapper):
-##            return DescrOperation.get_and_call(self, w_descr, w_obj,
-##                                               w_args, w_kwargs)
-##        else:
-##            try:
-##                obj = self.unwrap(w_obj)
-##                if hasattr(w_descr, '__get__'):
-##                    obj = w_descr.__get__(obj, type(obj))
-##                return obj(*w_args, **w_kwargs)
-##            except:
-##                self.reraise()
-
-    def get_and_call_function(self, w_descr, w_obj, *args_w, **kwargs_w):
+    def get_and_call_args(self, w_descr, w_obj, args):
         if isinstance(w_descr, CPyWrapper):
-            return DescrOperation.get_and_call_function(self, w_descr, w_obj,
-                                                        *args_w, **kwargs_w)
+            return DescrOperation.get_and_call_args(self, w_descr, w_obj, args)
         else:
             try:
                 obj = self.unwrap(w_obj)
                 if hasattr(w_descr, '__get__'):
                     obj = w_descr.__get__(obj, type(obj))
-                return obj(*args_w, **kwargs_w)
+                return obj(*args.args_w, **args.kwds_w)
             except:
                 #import traceback; traceback.print_exc()
                 self.reraise()



More information about the Pypy-commit mailing list