[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