[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