[pypy-svn] r56931 - in pypy/branch/garden-call-code/pypy: interpreter interpreter/test module/thread objspace objspace/std

pedronis at codespeak.net pedronis at codespeak.net
Sat Aug 2 16:17:13 CEST 2008


Author: pedronis
Date: Sat Aug  2 16:17:10 2008
New Revision: 56931

Modified:
   pypy/branch/garden-call-code/pypy/interpreter/baseobjspace.py
   pypy/branch/garden-call-code/pypy/interpreter/function.py
   pypy/branch/garden-call-code/pypy/interpreter/test/test_function.py
   pypy/branch/garden-call-code/pypy/interpreter/test/test_gateway.py
   pypy/branch/garden-call-code/pypy/interpreter/test/test_objspace.py
   pypy/branch/garden-call-code/pypy/module/thread/os_local.py
   pypy/branch/garden-call-code/pypy/objspace/descroperation.py
   pypy/branch/garden-call-code/pypy/objspace/std/typeobject.py
Log:
WIP

introduce space.call_obj_args instead of various uses of prepend. The final goal is in the common cases
not to have to put the obj in an argument at all, so not to need ArgumentPrepended anymore.

added tests to cover the area touched and related details



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	Sat Aug  2 16:17:10 2008
@@ -665,6 +665,9 @@
                     return True
         return False
 
+    def call_obj_args(self, w_callable, w_obj, args):
+        return self.call_args(w_callable, args.prepend(w_obj))
+
     def call(self, w_callable, w_args, w_kwds=None):
         args = Arguments.frompacked(self, w_args, w_kwds)
         return self.call_args(w_callable, args)

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	Sat Aug  2 16:17:10 2008
@@ -100,7 +100,7 @@
         stkargs = frame.make_arguments(nargs)
         args = stkargs.prepend(w_obj)
         try:
-            return self.call_args(args)
+            return self.call_args(args) # xxx Function.call_obj_args
         finally:
             if isinstance(stkargs, ArgumentsFromValuestack):
                 stkargs.frame = None
@@ -319,29 +319,29 @@
         space = self.space
         if self.w_instance is not None:
             # bound method
-            args = args.prepend(self.w_instance)
-        else:
-            # unbound method
-            w_firstarg = args.firstarg()
-            if w_firstarg is not None and space.is_true(
-                    space.abstract_isinstance(w_firstarg, self.w_class)):
-                pass  # ok
+            return space.call_obj_args(self.w_function, self.w_instance, args)
+
+        # unbound method
+        w_firstarg = args.firstarg()
+        if w_firstarg is not None and space.is_true(
+                space.abstract_isinstance(w_firstarg, self.w_class)):
+            pass  # ok
+        else:
+            myname = self.getname(space,"")
+            clsdescr = self.w_class.getname(space,"")
+            if clsdescr:
+                clsdescr+=" "
+            if w_firstarg is None:
+                instdescr = "nothing"
             else:
-                myname = self.getname(space,"")
-                clsdescr = self.w_class.getname(space,"")
-                if clsdescr:
-                    clsdescr+=" "
-                if w_firstarg is None:
-                    instdescr = "nothing"
-                else:
-                    instname = space.abstract_getclass(w_firstarg).getname(space,"")
-                    if instname:
-                        instname += " "
-                    instdescr = "%sinstance" %instname
-                msg = ("unbound method %s() must be called with %s"
-                       "instance as first argument (got %s instead)")  % (myname, clsdescr, instdescr)
-                raise OperationError(space.w_TypeError,
-                                     space.wrap(msg))
+                instname = space.abstract_getclass(w_firstarg).getname(space,"")
+                if instname:
+                    instname += " "
+                instdescr = "%sinstance" %instname
+            msg = ("unbound method %s() must be called with %s"
+                   "instance as first argument (got %s instead)")  % (myname, clsdescr, instdescr)
+            raise OperationError(space.w_TypeError,
+                                 space.wrap(msg))
         return space.call_args(self.w_function, args)
 
     def descr_method_get(self, w_obj, w_cls=None):

Modified: pypy/branch/garden-call-code/pypy/interpreter/test/test_function.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/test/test_function.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/test/test_function.py	Sat Aug  2 16:17:10 2008
@@ -84,6 +84,10 @@
         assert res[0] == 23
         assert res[1] == (42,)
 
+        res = func(23, *(42,))
+        assert res[0] == 23
+        assert res[1] == (42,)        
+
     def test_simple_kwargs(self):
         def func(arg1, **kwargs):
             return arg1, kwargs
@@ -91,6 +95,10 @@
         assert res[0] == 23
         assert res[1] == {'value': 42}
 
+        res = func(23, **{'value': 42})
+        assert res[0] == 23
+        assert res[1] == {'value': 42}
+
     def test_kwargs_sets_wrong_positional_raises(self):
         def func(arg1):
             pass
@@ -146,6 +154,15 @@
             return arg1, kw
         raises(TypeError, func, 42, **{'arg1': 23})
 
+    def test_kwargs_bound_blind(self):
+        class A(object):
+            def func(self, **kw):
+                return self, kw
+        func = A().func
+
+        func(self=23) # XXX different behavior from CPython
+        # xxx raises(TypeError, func, self=23)
+
     def test_kwargs_confusing_name(self):
         def func(self):    # 'self' conflicts with the interp-level
             return self*7  # argument to call_function()
@@ -177,6 +194,42 @@
         assert type(f.__doc__) is unicode
 
 class AppTestMethod: 
+    def test_simple_call(self):
+        class A(object):
+            def func(self, arg2):
+                return self, arg2
+        a = A()
+        res = a.func(42)
+        assert res[0] is a
+        assert res[1] == 42
+
+    def test_simple_varargs(self):
+        class A(object):
+            def func(self, *args):
+                return self, args
+        a = A()
+        res = a.func(42)
+        assert res[0] is a
+        assert res[1] == (42,)
+
+        res = a.func(*(42,))
+        assert res[0] is a
+        assert res[1] == (42,)        
+
+    def test_simple_kwargs(self):
+        class A(object):
+            def func(self, **kwargs):
+                return self, kwargs
+        a = A()
+            
+        res = a.func(value=42)
+        assert res[0] is a
+        assert res[1] == {'value': 42}
+
+        res = a.func(**{'value': 42})
+        assert res[0] is a
+        assert res[1] == {'value': 42}
+
     def test_get(self):
         def func(self): return self
         class Object(object): pass

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	Sat Aug  2 16:17:10 2008
@@ -459,3 +459,54 @@
 
         assert space.is_true(w_res)
         assert called == [w_app_f, w_app_f]       
+
+    def test_pass_trough_arguments(self):
+        space = self.space
+
+        called = []
+        
+        def f(space, __args__):
+            called.append(__args__)
+            a_w, _ = __args__.unpack()
+            return space.newtuple([space.wrap('f')]+a_w)
+
+        def g(space, w_self, __args__):
+            called.append(__args__)
+            a_w, _ = __args__.unpack()
+            return space.newtuple([space.wrap('g'), w_self, ]+a_w)
+
+        w_f = space.wrap(gateway.interp2app_temp(f,
+                         unwrap_spec=[gateway.ObjSpace,
+                                      gateway.Arguments]))
+
+        w_g = space.wrap(gateway.interp2app_temp(g,
+                         unwrap_spec=[gateway.ObjSpace,
+                                      gateway.W_Root,
+                                      gateway.Arguments]))
+
+        args = argument.Arguments(space, [space.wrap(7)])
+
+        w_res = space.call_args(w_f, args)
+        assert space.is_true(space.eq(w_res, space.wrap(('f', 7))))
+        
+        # white-box check for opt
+        assert called[0] is args
+        called = []
+
+        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       

Modified: pypy/branch/garden-call-code/pypy/interpreter/test/test_objspace.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/interpreter/test/test_objspace.py	(original)
+++ pypy/branch/garden-call-code/pypy/interpreter/test/test_objspace.py	Sat Aug  2 16:17:10 2008
@@ -180,6 +180,36 @@
         w_obj = space.wrap(-12)
         space.raises_w(space.w_ValueError, space.r_ulonglong_w, w_obj)
 
+    def test_call_obj_args(self):
+        from pypy.interpreter.argument import Arguments
+        
+        space = self.space
+
+        w_f = space.appexec([], """():
+    def f(x, y):
+        return (x, y)
+    return f
+""")
+
+        w_a = space.appexec([], """():
+    class A(object):
+        def __call__(self, x):
+            return x
+    return A()
+""")
+
+        w_9 = space.wrap(9)
+        w_1 = space.wrap(1)
+
+        w_res = space.call_obj_args(w_f, w_9, Arguments(space, [w_1]))
+
+        w_x, w_y = space.unpacktuple(w_res, 2)
+        assert w_x is w_9
+        assert w_y is w_1
+
+        w_res = space.call_obj_args(w_a, w_9, Arguments(space, []))        
+        assert w_res is w_9
+
 
 class TestModuleMinimal: 
     def test_sys_exists(self):

Modified: pypy/branch/garden-call-code/pypy/module/thread/os_local.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/module/thread/os_local.py	(original)
+++ pypy/branch/garden-call-code/pypy/module/thread/os_local.py	Sat Aug  2 16:17:10 2008
@@ -29,7 +29,7 @@
                 w_self = space.wrap(self)
                 w_type = space.type(w_self)
                 w_init = space.getattr(w_type, space.wrap("__init__"))
-                space.call_args(w_init, self.initargs.prepend(w_self))
+                space.call_obj_args(w_init, w_self, self.initargs)
             except:
                 # failed, forget w_dict and propagate the exception
                 del self.dicts[ident]

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	Sat Aug  2 16:17:10 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))
+            return descr.call_args(args.prepend(w_obj)) # xxx Function.call_obj_args
         else:
             w_impl = space.get(w_descr, w_obj)
             return space.call_args(w_impl, args)

Modified: pypy/branch/garden-call-code/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/branch/garden-call-code/pypy/objspace/std/typeobject.py	(original)
+++ pypy/branch/garden-call-code/pypy/objspace/std/typeobject.py	Sat Aug  2 16:17:10 2008
@@ -499,7 +499,7 @@
             return space.type(w_obj)
     # invoke the __new__ of the type
     w_newfunc = space.getattr(w_type, space.wrap('__new__'))
-    w_newobject = space.call_args(w_newfunc, __args__.prepend(w_type))
+    w_newobject = space.call_obj_args(w_newfunc, w_type, __args__)
     # maybe invoke the __init__ of the type
     if space.is_true(space.isinstance(w_newobject, w_type)):
         w_descr = space.lookup(w_newobject, '__init__')



More information about the Pypy-commit mailing list