[pypy-svn] r68349 - in pypy/branch/improve-kwd-args/pypy: interpreter interpreter/test module/__builtin__ module/pypyjit objspace/flow
pedronis at codespeak.net
pedronis at codespeak.net
Mon Oct 12 19:29:27 CEST 2009
Author: pedronis
Date: Mon Oct 12 19:29:24 2009
New Revision: 68349
Modified:
pypy/branch/improve-kwd-args/pypy/interpreter/argument.py
pypy/branch/improve-kwd-args/pypy/interpreter/pyframe.py
pypy/branch/improve-kwd-args/pypy/interpreter/pyopcode.py
pypy/branch/improve-kwd-args/pypy/interpreter/test/test_argument.py
pypy/branch/improve-kwd-args/pypy/interpreter/test/test_function.py
pypy/branch/improve-kwd-args/pypy/module/__builtin__/functional.py
pypy/branch/improve-kwd-args/pypy/module/pypyjit/interp_jit.py
pypy/branch/improve-kwd-args/pypy/objspace/flow/flowcontext.py
pypy/branch/improve-kwd-args/pypy/objspace/flow/objspace.py
Log:
(pedronis, cfbolz): progress and regress all mixed up in a blob of confusion:
- make the argument parsing not rely on dicts, which is JIT-friendlier
- at the moment Arguments objects are not immutable any more, which is a bad
idea
Modified: pypy/branch/improve-kwd-args/pypy/interpreter/argument.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/interpreter/argument.py (original)
+++ pypy/branch/improve-kwd-args/pypy/interpreter/argument.py Mon Oct 12 19:29:24 2009
@@ -3,6 +3,7 @@
"""
from pypy.interpreter.error import OperationError
+from pypy.rlib.debug import make_sure_not_resized
class Arguments(object):
"""
@@ -13,16 +14,21 @@
### Construction ###
- def __init__(self, space, args_w, kwds_w=None,
+ def __init__(self, space, args_w, keywords=None, keywords_w=None,
w_stararg=None, w_starstararg=None):
self.space = space
assert isinstance(args_w, list)
self.arguments_w = args_w
- from pypy.rlib.debug import make_sure_not_resized
+ self.keywords = keywords
+ self.keywords_w = keywords_w
+ if keywords is not None:
+ assert keywords_w is not None
+ assert len(keywords_w) == len(keywords)
+ make_sure_not_resized(self.keywords)
+ make_sure_not_resized(self.keywords_w)
+
make_sure_not_resized(self.arguments_w)
- self.kwds_w = kwds_w
- self.w_stararg = w_stararg
- self.w_starstararg = w_starstararg
+ self._combine_wrapped(w_stararg, w_starstararg)
@staticmethod
def factory(space, args_w, kwds_w=None,
@@ -31,65 +37,52 @@
w_stararg, w_starstararg)
def num_args(self): # only used in module/__builtin__/interp_classobj.py
- self._unpack()
return len(self.arguments_w)
def num_kwds(self): # only used in module/__builtin__/interp_classobj.py
- self._unpack()
- return len(self.kwds_w)
+ return len(self.keywords)
def __repr__(self):
""" NOT_RPYTHON """
- if self.w_starstararg is not None:
- return '%s(%s, %s, %s, %s)' % (self.__class__,
- self.arguments_w,
- self.kwds_w,
- self.w_stararg,
- self.w_starstararg)
- if self.w_stararg is None:
- if not self.kwds_w:
- return '%s(%s)' % (self.__class__, self.arguments_w,)
- else:
- return '%s(%s, %s)' % (self.__class__, self.arguments_w,
- self.kwds_w)
+ if not self.keywords:
+ return '%s(%s)' % (self.__class__, self.arguments_w,)
else:
return '%s(%s, %s, %s)' % (self.__class__, self.arguments_w,
- self.kwds_w, self.w_stararg)
+ self.keywords, self.keywords_w)
### Manipulation ###
def unpack(self): # used often
"Return a ([w1,w2...], {'kw':w3...}) pair."
- self._unpack()
- return self.arguments_w, self.kwds_w
+ # XXX may want to change that later
+ kwds_w = {}
+ if self.keywords:
+ for i in range(len(self.keywords)):
+ kwds_w[self.keywords[i]] = self.keywords_w[i]
+ return self.arguments_w, kwds_w
def prepend(self, w_firstarg): # used often
"Return a new Arguments with a new argument inserted first."
return self.factory(self.space, [w_firstarg] + self.arguments_w,
- self.kwds_w, self.w_stararg, self.w_starstararg)
+ self.keywords, self.keywords_w)
- def _unpack(self):
- "unpack the *arg and **kwd into w_arguments and kwds_w"
- # --- unpack the * argument now ---
- if self.w_stararg is not None:
+ def _combine_wrapped(self, w_stararg, w_starstararg):
+ "unpack the *arg and **kwd into arguments_w and keywords_w"
+ # unpack the * arguments
+ if w_stararg is not None:
self.arguments_w = (self.arguments_w +
- self.space.unpackiterable(self.w_stararg))
- self.w_stararg = None
- # --- unpack the ** argument now ---
- if self.kwds_w is None:
- self.kwds_w = {}
- if self.w_starstararg is not None:
+ self.space.viewiterable(w_stararg))
+ # unpack the ** arguments
+ if w_starstararg is not None:
space = self.space
- w_starstararg = self.w_starstararg
- # maybe we could allow general mappings?
if not space.is_true(space.isinstance(w_starstararg, space.w_dict)):
raise OperationError(space.w_TypeError,
space.wrap("argument after ** must be "
"a dictionary"))
- # don't change the original yet,
- # in case something goes wrong
- d = self.kwds_w.copy()
+ keywords_w = [None] * space.int_w(space.len(w_starstararg))
+ keywords = [None] * space.int_w(space.len(w_starstararg))
+ i = 0
for w_key in space.unpackiterable(w_starstararg):
try:
key = space.str_w(w_key)
@@ -98,14 +91,20 @@
raise
raise OperationError(space.w_TypeError,
space.wrap("keywords must be strings"))
- if key in d:
+ if self.keywords and key in self.keywords:
raise OperationError(self.space.w_TypeError,
self.space.wrap("got multiple values "
"for keyword argument "
"'%s'" % key))
- d[key] = space.getitem(w_starstararg, w_key)
- self.kwds_w = d
- self.w_starstararg = None
+ keywords[i] = key
+ keywords_w[i] = space.getitem(w_starstararg, w_key)
+ i += 1
+ if self.keywords is None:
+ self.keywords = keywords
+ self.keywords_w = keywords_w
+ else:
+ self.keywords += keywords
+ self.keywords_w += keywords_w
def fixedunpack(self, argcount):
# used by ./objspace/std/typeobject.py
@@ -113,16 +112,10 @@
# ./annotation/description.py
"""The simplest argument parsing: get the 'argcount' arguments,
or raise a real ValueError if the length is wrong."""
- if bool(self.kwds_w) or (self.w_starstararg is not None and
- self.space.is_true(self.w_starstararg)):
+ if self.keywords:
raise ValueError, "no keyword arguments expected"
if len(self.arguments_w) > argcount:
raise ValueError, "too many arguments (%d expected)" % argcount
- if self.w_stararg is not None:
- self.arguments_w = (self.arguments_w +
- self.space.viewiterable(self.w_stararg,
- argcount - len(self.arguments_w)))
- self.w_stararg = None
elif len(self.arguments_w) < argcount:
raise ValueError, "not enough arguments (%d expected)" % argcount
return self.arguments_w
@@ -135,15 +128,7 @@
"Return the first argument for inspection."
if self.arguments_w:
return self.arguments_w[0]
- if self.w_stararg is None:
- return None
- w_iter = self.space.iter(self.w_stararg)
- try:
- return self.space.next(w_iter)
- except OperationError, e:
- if not e.match(self.space, self.space.w_StopIteration):
- raise
- return None
+ return None
### Parsing for function calls ###
@@ -173,27 +158,15 @@
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) + upfront == co_argcount and
- has_vararg and
- self.space.is_w(self.space.type(self.w_stararg),
- self.space.w_tuple)):
- pass
- else:
- self._unpack() # sets self.w_stararg to None
- # always unpack the ** arguments
- if self.w_starstararg is not None:
- self._unpack()
-
args_w = self.arguments_w
+ assert args_w is not None, "tried to match arguments again"
num_args = len(args_w)
- kwds_w = self.kwds_w
+ keywords = self.keywords
+ keywords_w = self.keywords_w
num_kwds = 0
- if kwds_w is not None:
- num_kwds = len(kwds_w)
+ if keywords is not None:
+ num_kwds = len(keywords)
avail = num_args + upfront
@@ -208,29 +181,36 @@
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,
- # which were put into place by prepend(). This way, keywords do
- # not conflict with the hidden extra argument bound by methods.
- if kwds_w and input_argcount > blindargs:
- for name in argnames[blindargs:input_argcount]:
- if name in kwds_w:
- raise ArgErrMultipleValues(name)
-
- remainingkwds_w = self.kwds_w
+ # the code assumes that keywords can potentially be large, but that
+ # argnames is typically not too large
+ num_remainingkwds = num_kwds
+ if keywords:
+ for i in range(num_kwds):
+ name = keywords[i]
+ try:
+ j = argnames.index(name)
+ except ValueError:
+ continue
+ if j < input_argcount:
+ # check that no keyword argument conflicts with these note
+ # that for this purpose we ignore the first blindargs,
+ # which were put into place by prepend(). This way,
+ # keywords do not conflict with the hidden extra argument
+ # bound by methods.
+ if blindargs <= j:
+ raise ArgErrMultipleValues(name)
+ else:
+ assert scope_w[j] is None
+ scope_w[j] = keywords_w[i]
+ keywords[i] = None # mark as used
+ num_remainingkwds -= 1
missing = 0
if input_argcount < co_argcount:
- if remainingkwds_w is None:
- remainingkwds_w = {}
- else:
- remainingkwds_w = remainingkwds_w.copy()
- # 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[i] = remainingkwds_w[name]
- del remainingkwds_w[name]
+ if scope_w[i] is not None:
+ pass
elif i >= def_first:
scope_w[i] = defaults_w[i-def_first]
else:
@@ -239,23 +219,19 @@
# keyword arguments, which will be checked for below.
missing += 1
-
# collect extra positional arguments into the *vararg
if has_vararg:
- if self.w_stararg is None: # common case
- args_left = co_argcount - upfront
- if args_left < 0: # check required by rpython
- assert extravarargs is not None
- starargs_w = extravarargs
- if num_args:
- starargs_w = starargs_w + args_w
- 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
+ args_left = co_argcount - upfront
+ if args_left < 0: # check required by rpython
+ assert extravarargs is not None
+ starargs_w = extravarargs
+ if num_args:
+ starargs_w = starargs_w + args_w
+ elif num_args > args_left:
+ starargs_w = args_w[args_left:]
+ else:
+ starargs_w = []
+ scope_w[co_argcount] = self.space.newtuple(starargs_w)
elif avail > co_argcount:
raise ArgErrCount(avail, num_kwds,
(co_argcount, has_vararg, has_kwarg),
@@ -264,18 +240,23 @@
# collect extra keyword arguments into the **kwarg
if has_kwarg:
w_kwds = self.space.newdict()
- if remainingkwds_w:
- for key, w_value in remainingkwds_w.items():
- self.space.setitem(w_kwds, self.space.wrap(key), w_value)
+ if num_remainingkwds:
+ for i in range(len(keywords)):
+ key = keywords[i]
+ if key is not None:
+ self.space.setitem(w_kwds, self.space.wrap(key), keywords_w[i])
scope_w[co_argcount + has_vararg] = w_kwds
- elif remainingkwds_w:
- raise ArgErrUnknownKwds(remainingkwds_w)
+ elif num_remainingkwds:
+ raise ArgErrUnknownKwds(num_remainingkwds, keywords)
if missing:
raise ArgErrCount(avail, num_kwds,
(co_argcount, has_vararg, has_kwarg),
defaults_w, missing)
+ self.arguments_w = None
+ self.keywords = None
+ self.keywords_w = None
return co_argcount + has_vararg + has_kwarg
@@ -358,14 +339,11 @@
space.setitem(w_kwds, space.wrap(key), w_value)
return w_args, w_kwds
+ @staticmethod
def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w):
# used by geninterped code
args_w = data_w[:shape_cnt]
- p = shape_cnt
- kwds_w = {}
- for i in range(len(shape_keys)):
- kwds_w[shape_keys[i]] = data_w[p]
- p += 1
+ p = end_keys = shape_cnt + len(shape_keys)
if shape_star:
w_star = data_w[p]
p += 1
@@ -376,27 +354,64 @@
p += 1
else:
w_starstar = None
- return Arguments(space, args_w, kwds_w, w_star, w_starstar)
- fromshape = staticmethod(fromshape)
+ return Arguments(space, args_w, list(shape_keys),
+ data_w[shape_cnt:end_keys], w_star,
+ w_starstar)
+
+ def copy(self):
+ if self.keywords is None:
+ keywords = None
+ keywords_w = None
+ else:
+ keywords = self.keywords[:]
+ keywords_w = self.keywords_w[:]
+ return Arguments(self.space, self.arguments_w[:], keywords,
+ keywords_w)
- def normalize(self):
- """Return an instance of the Arguments class. (Instances of other
- classes may not be suitable for long-term storage or multiple
- usage.) Also force the type and validity of the * and ** arguments
- to be checked now.
- """
- args_w, kwds_w = self.unpack()
- return Arguments(self.space, args_w, kwds_w)
+class ArgumentsForTranslation(Arguments):
+ def __init__(self, space, args_w, keywords=None, keywords_w=None,
+ w_stararg=None, w_starstararg=None):
+ self.w_stararg = w_stararg
+ self.w_starstararg = w_starstararg
+ self.combine_has_happened = False
+ Arguments.__init__(self, space, args_w, keywords, keywords_w)
+ def combine_if_necessary(self):
+ if self.combine_has_happened:
+ return
+ self._combine_wrapped(self.w_stararg, self.w_starstararg)
+ self.combine_has_happened = True
-class ArgumentsForTranslation(Arguments):
@staticmethod
def factory(space, args_w, kwds_w=None,
w_stararg=None, w_starstararg=None):
return ArgumentsForTranslation(space, args_w, kwds_w,
w_stararg, w_starstararg)
+ def copy(self):
+ if self.keywords is None:
+ keywords = None
+ keywords_w = None
+ else:
+ keywords = self.keywords[:]
+ keywords_w = self.keywords_w[:]
+ return ArgumentsForTranslation(self.space, self.arguments_w[:], keywords,
+ keywords_w, self.w_stararg,
+ self.w_starstararg)
+
+ def _match_signature(self, w_firstarg, scope_w, argnames, has_vararg=False,
+ has_kwarg=False, defaults_w=[], blindargs=0):
+ self.combine_if_necessary()
+ # _match_signature is destructive
+ return Arguments._match_signature(
+ self, w_firstarg, scope_w, argnames, has_vararg, has_kwarg,
+ defaults_w, blindargs)
+
+ def unpack(self):
+ self.combine_if_necessary()
+ return Arguments.unpack(self)
+
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.
@@ -444,27 +459,26 @@
args_w[i + datalen] = stararg_w[i]
assert len(args_w) == need_cnt
- kwds_w = {}
+ keywords = []
+ keywords_w = []
for key in need_kwds:
- kwds_w[key] = unfiltered_kwds_w[key]
+ keywords.append(key)
+ keywords_w.append(unfiltered_kwds_w[key])
- return ArgumentsForTranslation(self.space, args_w, kwds_w)
+ return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w)
@staticmethod
def frompacked(space, w_args=None, w_kwds=None):
raise NotImplementedError("go away")
+ @staticmethod
def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w):
# used by
# ./rpython/callparse.py
# ./rpython/rbuiltin.py
# ./annotation/bookkeeper.py
args_w = data_w[:shape_cnt]
- p = shape_cnt
- kwds_w = {}
- for i in range(len(shape_keys)):
- kwds_w[shape_keys[i]] = data_w[p]
- p += 1
+ p = end_keys = shape_cnt + len(shape_keys)
if shape_star:
w_star = data_w[p]
p += 1
@@ -475,14 +489,16 @@
p += 1
else:
w_starstar = None
- return ArgumentsForTranslation(space, args_w, kwds_w, w_star, w_starstar)
- fromshape = staticmethod(fromshape)
+ return ArgumentsForTranslation(space, args_w, list(shape_keys),
+ data_w[shape_cnt:end_keys], w_star,
+ w_starstar)
def flatten(self):
# used by ./objspace/flow/objspace.py
""" Argument <-> list of w_objects together with "shape" information """
shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape()
- data_w = self.arguments_w + [self.kwds_w[key] for key in shape_keys]
+ data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)]
+ for key in shape_keys]
if shape_star:
data_w.append(self.w_stararg)
if shape_stst:
@@ -490,9 +506,10 @@
return (shape_cnt, shape_keys, shape_star, shape_stst), data_w
def _rawshape(self, nextra=0):
+ assert not self.combine_has_happened
shape_cnt = len(self.arguments_w)+nextra # Number of positional args
- if self.kwds_w:
- shape_keys = self.kwds_w.keys() # List of keywords (strings)
+ if self.keywords:
+ shape_keys = self.keywords[:] # List of keywords (strings)
shape_keys.sort()
else:
shape_keys = []
@@ -581,11 +598,14 @@
class ArgErrUnknownKwds(ArgErr):
- def __init__(self, kwds_w):
+ def __init__(self, num_remainingkwds, keywords):
self.kwd_name = ''
- self.num_kwds = len(kwds_w)
- if self.num_kwds == 1:
- self.kwd_name = kwds_w.keys()[0]
+ self.num_kwds = num_remainingkwds
+ if num_remainingkwds == 1:
+ for kwd_name in keywords:
+ if kwd_name is not None:
+ self.kwd_name = kwd_name
+ break
def getmsg(self, fnname):
if self.num_kwds == 1:
Modified: pypy/branch/improve-kwd-args/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/interpreter/pyframe.py (original)
+++ pypy/branch/improve-kwd-args/pypy/interpreter/pyframe.py Mon Oct 12 19:29:24 2009
@@ -184,17 +184,6 @@
self.valuestackdepth = hint(depth, promote=True)
return w_object
- def popstrdictvalues(self, n):
- dic_w = {}
- while True:
- n -= 1
- if n < 0:
- break
- w_value = self.popvalue()
- w_key = self.popvalue()
- key = self.space.str_w(w_key)
- dic_w[key] = w_value
- return dic_w
# we need two popvalues that return different data types:
# one in case we want list another in case of tuple
@@ -282,8 +271,8 @@
def make_arguments(self, nargs):
return Arguments(self.space, self.peekvalues(nargs))
- def argument_factory(self, arguments, keywords, w_star, w_starstar):
- return Arguments(self.space, arguments, keywords, w_star, w_starstar)
+ def argument_factory(self, arguments, keywords, keywords_w, w_star, w_starstar):
+ return Arguments(self.space, arguments, keywords, keywords_w, w_star, w_starstar)
@jit.dont_look_inside
def descr__reduce__(self, space):
Modified: pypy/branch/improve-kwd-args/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/interpreter/pyopcode.py (original)
+++ pypy/branch/improve-kwd-args/pypy/interpreter/pyopcode.py Mon Oct 12 19:29:24 2009
@@ -9,7 +9,6 @@
from pypy.interpreter.baseobjspace import UnpackValueError, Wrappable
from pypy.interpreter import gateway, function, eval
from pypy.interpreter import pyframe, pytraceback
-from pypy.interpreter.argument import Arguments
from pypy.interpreter.pycode import PyCode
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib.objectmodel import we_are_translated
@@ -896,11 +895,24 @@
n_arguments = oparg & 0xff
n_keywords = (oparg>>8) & 0xff
- keywords = None
if n_keywords:
- keywords = f.popstrdictvalues(n_keywords)
+ keywords = [None] * n_keywords
+ keywords_w = [None] * n_keywords
+ dic_w = {}
+ while True:
+ n_keywords -= 1
+ if n_keywords < 0:
+ break
+ w_value = f.popvalue()
+ w_key = f.popvalue()
+ key = f.space.str_w(w_key)
+ keywords[n_keywords] = key
+ keywords_w[n_keywords] = w_value
+ else:
+ keywords = None
+ keywords_w = None
arguments = f.popvalues(n_arguments)
- args = f.argument_factory(arguments, keywords, w_star, w_starstar)
+ args = f.argument_factory(arguments, keywords, keywords_w, w_star, w_starstar)
w_function = f.popvalue()
if we_are_jitted():
w_result = f.space.call_args(w_function, args)
Modified: pypy/branch/improve-kwd-args/pypy/interpreter/test/test_argument.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/interpreter/test/test_argument.py (original)
+++ pypy/branch/improve-kwd-args/pypy/interpreter/test/test_argument.py Mon Oct 12 19:29:24 2009
@@ -11,6 +11,9 @@
def is_true(self, obj):
return bool(obj)
+ def viewiterable(self, it):
+ return list(it)
+
def unpackiterable(self, it):
return list(it)
@@ -29,6 +32,12 @@
def str_w(self, s):
return str(s)
+ def len(self, x):
+ return len(x)
+
+ def int_w(self, x):
+ return x
+
def isinstance(self, obj, cls):
return isinstance(obj, cls)
@@ -47,23 +56,31 @@
args._match_signature(None, l, [])
assert len(l) == 0
l = [None, None]
+ args = Arguments(space, [])
py.test.raises(ArgErr, args._match_signature, None, l, ["a"])
+ args = Arguments(space, [])
py.test.raises(ArgErr, args._match_signature, None, l, ["a"],
has_vararg=True)
+ args = Arguments(space, [])
l = [None]
args._match_signature(None, l, ["a"], defaults_w=[1])
assert l == [1]
+ args = Arguments(space, [])
l = [None]
args._match_signature(None, l, [], has_vararg=True)
assert l == [()]
+ args = Arguments(space, [])
l = [None]
args._match_signature(None, l, [], has_kwarg=True)
assert l == [{}]
+ args = Arguments(space, [])
l = [None, None]
py.test.raises(ArgErr, args._match_signature, 41, l, [])
+ args = Arguments(space, [])
l = [None]
args._match_signature(1, l, ["a"])
assert l == [1]
+ args = Arguments(space, [])
l = [None]
args._match_signature(1, l, [], has_vararg=True)
assert l == [(1,)]
@@ -73,29 +90,37 @@
values = [4, 5, 6, 7]
for havefirstarg in [0, 1]:
for i in range(len(values)-havefirstarg):
- args = values[havefirstarg:i+havefirstarg]
+ arglist = values[havefirstarg:i+havefirstarg]
starargs = tuple(values[i+havefirstarg:])
if havefirstarg:
firstarg = values[0]
else:
firstarg = None
- args = Arguments(space, args, w_stararg=starargs)
+ args = Arguments(space, arglist, w_stararg=starargs)
l = [None, None, None, None]
args._match_signature(firstarg, l, ["a", "b", "c", "d"])
assert l == [4, 5, 6, 7]
+ args = Arguments(space, arglist, w_stararg=starargs)
l = [None, None, None, None, None, None]
py.test.raises(ArgErr, args._match_signature, firstarg, l, ["a"])
+ args = Arguments(space, arglist, w_stararg=starargs)
+ l = [None, None, None, None, None, None]
py.test.raises(ArgErr, args._match_signature, firstarg, l, ["a", "b", "c", "d", "e"])
+ args = Arguments(space, arglist, w_stararg=starargs)
+ l = [None, None, None, None, None, None]
py.test.raises(ArgErr, args._match_signature, firstarg, l, ["a", "b", "c", "d", "e"],
has_vararg=True)
l = [None, None, None, None, None]
+ args = Arguments(space, arglist, w_stararg=starargs)
args._match_signature(firstarg, l, ["a", "b", "c", "d", "e"], defaults_w=[1])
assert l == [4, 5, 6, 7, 1]
for j in range(len(values)):
l = [None] * (j + 1)
+ args = Arguments(space, arglist, w_stararg=starargs)
args._match_signature(firstarg, l, ["a", "b", "c", "d", "e"][:j], has_vararg=True)
assert l == values[:j] + [tuple(values[j:])]
l = [None, None, None, None, None]
+ args = Arguments(space, arglist, w_stararg=starargs)
args._match_signature(firstarg, l, ["a", "b", "c", "d"], has_kwarg=True)
assert l == [4, 5, 6, 7, {}]
@@ -104,24 +129,33 @@
for i in range(3):
kwds = [("c", 3)]
kwds_w = dict(kwds[:i])
+ keywords = kwds_w.keys()
+ keywords_w = kwds_w.values()
w_kwds = dict(kwds[i:])
if i == 2:
w_kwds = None
- args = Arguments(space, [1, 2], kwds_w, w_starstararg=w_kwds)
+ assert len(keywords) == len(keywords_w)
+ args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds)
l = [None, None, None]
args._match_signature(None, l, ["a", "b", "c"], defaults_w=[4])
assert l == [1, 2, 3]
+ args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds)
l = [None, None, None, None]
args._match_signature(None, l, ["a", "b", "b1", "c"], defaults_w=[4, 5])
assert l == [1, 2, 4, 3]
+ args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds)
l = [None, None, None, None]
args._match_signature(None, l, ["a", "b", "c", "d"], defaults_w=[4, 5])
assert l == [1, 2, 3, 5]
+ args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds)
l = [None, None, None, None]
py.test.raises(ArgErr, args._match_signature, None, l,
["c", "b", "a", "d"], defaults_w=[4, 5])
+ args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds)
+ l = [None, None, None, None]
py.test.raises(ArgErr, args._match_signature, None, l,
["a", "b", "c1", "d"], defaults_w=[4, 5])
+ args = Arguments(space, [1, 2], keywords[:], keywords_w[:], w_starstararg=w_kwds)
l = [None, None, None]
args._match_signature(None, l, ["a", "b"], has_kwarg=True)
assert l == [1, 2, {'c': 3}]
@@ -131,26 +165,26 @@
kwds = [("c", 3), ('d', 4)]
for i in range(4):
kwds_w = dict(kwds[:i])
+ keywords = kwds_w.keys()
+ keywords_w = kwds_w.values()
w_kwds = dict(kwds[i:])
if i == 3:
w_kwds = None
- args = Arguments(space, [1, 2], kwds_w, w_starstararg=w_kwds)
+ args = Arguments(space, [1, 2], keywords, keywords_w, w_starstararg=w_kwds)
l = [None, None, None, None]
args._match_signature(None, l, ["a", "b", "c"], has_kwarg=True)
assert l == [1, 2, 3, {'d': 4}]
def test_duplicate_kwds(self):
space = DummySpace()
- args = Arguments(space, [], {"a": 1}, w_starstararg={"a": 2})
- excinfo = py.test.raises(OperationError, args._match_signature, None,
- [None], [], has_kwarg=True)
+ excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"],
+ [1], w_starstararg={"a": 2})
assert excinfo.value.w_type is TypeError
def test_starstararg_wrong_type(self):
space = DummySpace()
- args = Arguments(space, [], {"a": 1}, w_starstararg="hello")
- excinfo = py.test.raises(OperationError, args._match_signature, None,
- [None], [], has_kwarg=True)
+ excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"],
+ [1], w_starstararg="hello")
assert excinfo.value.w_type is TypeError
def test_unwrap_error(self):
@@ -163,14 +197,12 @@
raise OperationError(ValueError, None)
return str(w)
space.str_w = str_w
- args = Arguments(space, [], {"a": 1}, w_starstararg={None: 1})
- excinfo = py.test.raises(OperationError, args._match_signature, None,
- [None], [], has_kwarg=True)
+ excinfo = py.test.raises(OperationError, Arguments, space, [],
+ ["a"], [1], w_starstararg={None: 1})
assert excinfo.value.w_type is TypeError
assert excinfo.value.w_value is not None
- args = Arguments(space, [], {"a": 1}, w_starstararg={valuedummy: 1})
- excinfo = py.test.raises(OperationError, args._match_signature, None,
- [None], [], has_kwarg=True)
+ excinfo = py.test.raises(OperationError, Arguments, space, [],
+ ["a"], [1], w_starstararg={valuedummy: 1})
assert excinfo.value.w_type is ValueError
assert excinfo.value.w_value is None
@@ -180,142 +212,153 @@
kwds = [("a", 3), ('b', 4)]
for i in range(4):
kwds_w = dict(kwds[:i])
+ keywords = kwds_w.keys()
+ keywords_w = kwds_w.values()
w_kwds = dict(kwds[i:])
if i == 3:
w_kwds = None
- args = Arguments(space, [1, 2], kwds_w, w_starstararg=w_kwds)
+ args = Arguments(space, [1, 2], keywords[:], keywords_w[:],
+ w_starstararg=w_kwds)
l = [None, None, None]
args._match_signature(None, l, ["a", "b"], has_kwarg=True, blindargs=2)
assert l == [1, 2, {'a':3, 'b': 4}]
+ args = Arguments(space, [1, 2], keywords[:], keywords_w[:],
+ w_starstararg=w_kwds)
+ l = [None, None, None]
py.test.raises(ArgErrUnknownKwds, args._match_signature, None, l,
["a", "b"], blindargs=2)
+def make_arguments_for_translation(space, args_w, keywords_w={},
+ w_stararg=None, w_starstararg=None):
+ return ArgumentsForTranslation(space, args_w, keywords_w.keys(),
+ keywords_w.values(), w_stararg,
+ w_starstararg)
class TestArgumentsForTranslation(object):
def test_unmatch_signature(self):
space = DummySpace()
- args = ArgumentsForTranslation(space, [1,2,3])
+ args = make_arguments_for_translation(space, [1,2,3])
sig = (['a', 'b', 'c'], None, None)
- data = args.match_signature(sig, [])
+ data = args.copy().match_signature(sig, [])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
- args = ArgumentsForTranslation(space, [1])
+ args = make_arguments_for_translation(space, [1])
sig = (['a', 'b', 'c'], None, None)
- data = args.match_signature(sig, [2, 3])
+ data = args.copy().match_signature(sig, [2, 3])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
- args = ArgumentsForTranslation(space, [1,2,3,4,5])
+ args = make_arguments_for_translation(space, [1,2,3,4,5])
sig = (['a', 'b', 'c'], 'r', None)
- data = args.match_signature(sig, [])
+ data = args.copy().match_signature(sig, [])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
- args = ArgumentsForTranslation(space, [1], {'c': 3, 'b': 2})
+ args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
sig = (['a', 'b', 'c'], None, None)
- data = args.match_signature(sig, [])
+ data = args.copy().match_signature(sig, [])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
- args = ArgumentsForTranslation(space, [1], {'c': 5})
+ args = make_arguments_for_translation(space, [1], {'c': 5})
sig = (['a', 'b', 'c'], None, None)
- data = args.match_signature(sig, [2, 3])
+ data = args.copy().match_signature(sig, [2, 3])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
- args = ArgumentsForTranslation(space, [1], {'c': 5, 'd': 7})
+ args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
sig = (['a', 'b', 'c'], None, 'kw')
- data = args.match_signature(sig, [2, 3])
+ data = args.copy().match_signature(sig, [2, 3])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
- args = ArgumentsForTranslation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
+ args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
sig = (['a', 'b', 'c'], 'r', 'kw')
- data = args.match_signature(sig, [2, 3])
+ data = args.copy().match_signature(sig, [2, 3])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
- args = ArgumentsForTranslation(space, [], {},
+ args = make_arguments_for_translation(space, [], {},
w_stararg=[1],
w_starstararg={'c': 5, 'd': 7})
sig = (['a', 'b', 'c'], None, 'kw')
- data = args.match_signature(sig, [2, 3])
+ data = args.copy().match_signature(sig, [2, 3])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
- args = ArgumentsForTranslation(space, [1,2], {'g': 9},
+ args = make_arguments_for_translation(space, [1,2], {'g': 9},
w_stararg=[3,4,5],
w_starstararg={'e': 5, 'd': 7})
sig = (['a', 'b', 'c'], 'r', 'kw')
- data = args.match_signature(sig, [2, 3])
+ data = args.copy().match_signature(sig, [2, 3])
new_args = args.unmatch_signature(sig, data)
assert args.unpack() == new_args.unpack()
def test_rawshape(self):
space = DummySpace()
- args = ArgumentsForTranslation(space, [1,2,3])
+ args = make_arguments_for_translation(space, [1,2,3])
assert rawshape(args) == (3, (), False, False)
- args = ArgumentsForTranslation(space, [1])
+ args = make_arguments_for_translation(space, [1])
assert rawshape(args, 2) == (3, (), False, False)
- args = ArgumentsForTranslation(space, [1,2,3,4,5])
+ args = make_arguments_for_translation(space, [1,2,3,4,5])
assert rawshape(args) == (5, (), False, False)
- args = ArgumentsForTranslation(space, [1], {'c': 3, 'b': 2})
+ args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
assert rawshape(args) == (1, ('b', 'c'), False, False)
- args = ArgumentsForTranslation(space, [1], {'c': 5})
+ args = make_arguments_for_translation(space, [1], {'c': 5})
assert rawshape(args) == (1, ('c', ), False, False)
- args = ArgumentsForTranslation(space, [1], {'c': 5, 'd': 7})
+ args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
assert rawshape(args) == (1, ('c', 'd'), False, False)
- args = ArgumentsForTranslation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
+ args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
assert rawshape(args) == (5, ('d', 'e'), False, False)
- args = ArgumentsForTranslation(space, [], {},
+ args = make_arguments_for_translation(space, [], {},
w_stararg=[1],
w_starstararg={'c': 5, 'd': 7})
assert rawshape(args) == (0, (), True, True)
- args = ArgumentsForTranslation(space, [1,2], {'g': 9},
+ args = make_arguments_for_translation(space, [1,2], {'g': 9},
w_stararg=[3,4,5],
w_starstararg={'e': 5, 'd': 7})
assert rawshape(args) == (2, ('g', ), True, True)
def test_flatten(self):
space = DummySpace()
- args = ArgumentsForTranslation(space, [1,2,3])
+ args = make_arguments_for_translation(space, [1,2,3])
assert args.flatten() == ((3, (), False, False), [1, 2, 3])
- args = ArgumentsForTranslation(space, [1])
+ args = make_arguments_for_translation(space, [1])
assert args.flatten() == ((1, (), False, False), [1])
- args = ArgumentsForTranslation(space, [1,2,3,4,5])
+ args = make_arguments_for_translation(space, [1,2,3,4,5])
assert args.flatten() == ((5, (), False, False), [1,2,3,4,5])
- args = ArgumentsForTranslation(space, [1], {'c': 3, 'b': 2})
+ args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3])
- args = ArgumentsForTranslation(space, [1], {'c': 5})
+ args = make_arguments_for_translation(space, [1], {'c': 5})
assert args.flatten() == ((1, ('c', ), False, False), [1, 5])
- args = ArgumentsForTranslation(space, [1], {'c': 5, 'd': 7})
+ args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7])
- args = ArgumentsForTranslation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
+ args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5])
- args = ArgumentsForTranslation(space, [], {},
+ args = make_arguments_for_translation(space, [], {},
w_stararg=[1],
w_starstararg={'c': 5, 'd': 7})
assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}])
- args = ArgumentsForTranslation(space, [1,2], {'g': 9},
+ args = make_arguments_for_translation(space, [1,2], {'g': 9},
w_stararg=[3,4,5],
w_starstararg={'e': 5, 'd': 7})
assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}])
@@ -324,7 +367,7 @@
space = DummySpace()
var = object()
shape = ((2, ('g', ), True, False), [1, 2, 9, var])
- args = ArgumentsForTranslation(space, [1,2], {'g': 9},
+ args = make_arguments_for_translation(space, [1,2], {'g': 9},
w_stararg=var)
assert args.flatten() == shape
Modified: pypy/branch/improve-kwd-args/pypy/interpreter/test/test_function.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/interpreter/test/test_function.py (original)
+++ pypy/branch/improve-kwd-args/pypy/interpreter/test/test_function.py Mon Oct 12 19:29:24 2009
@@ -480,20 +480,20 @@
w_meth1 = descr_function_get(space, func, obj1, space.type(obj1))
meth1 = space.unwrap(w_meth1)
assert isinstance(meth1, Method)
- assert meth1.call_args(args) == obj1
+ assert meth1.call_args(args.copy()) == obj1
# Check method returned from method.__get__()
# --- meth1 is already bound so meth1.__get__(*) is meth1.
w_meth2 = meth1.descr_method_get(obj2, space.type(obj2))
meth2 = space.unwrap(w_meth2)
assert isinstance(meth2, Method)
- assert meth2.call_args(args) == obj1
+ assert meth2.call_args(args.copy()) == obj1
# Check method returned from unbound_method.__get__()
w_meth3 = descr_function_get(space, func, None, space.type(obj2))
meth3 = space.unwrap(w_meth3)
w_meth4 = meth3.descr_method_get(obj2, space.w_None)
meth4 = space.unwrap(w_meth4)
assert isinstance(meth4, Method)
- assert meth4.call_args(args) == obj2
+ assert meth4.call_args(args.copy()) == obj2
# Check method returned from unbound_method.__get__()
# --- with an incompatible class
w_meth5 = meth3.descr_method_get(space.wrap('hello'), space.w_str)
Modified: pypy/branch/improve-kwd-args/pypy/module/__builtin__/functional.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/module/__builtin__/functional.py (original)
+++ pypy/branch/improve-kwd-args/pypy/module/__builtin__/functional.py Mon Oct 12 19:29:24 2009
@@ -108,6 +108,7 @@
compare = space.gt
else:
compare = space.lt
+ # XXXXXXXXX
args, kwargs = arguments.unpack()
if len(args) > 1:
w_sequence = space.newtuple(args)
@@ -120,9 +121,7 @@
w_key = kwargs["key"]
except KeyError:
w_key = None
- else:
- del kwargs["key"]
- if kwargs:
+ if len(kwargs) != 1:
msg = "%s() got unexpected keyword argument" % (implementation_of,)
raise OperationError(space.w_TypeError, space.wrap(msg))
w_iter = space.iter(w_sequence)
Modified: pypy/branch/improve-kwd-args/pypy/module/pypyjit/interp_jit.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/module/pypyjit/interp_jit.py (original)
+++ pypy/branch/improve-kwd-args/pypy/module/pypyjit/interp_jit.py Mon Oct 12 19:29:24 2009
@@ -103,6 +103,7 @@
* set_param(name=value, ...) # as keyword arguments
* set_param("name=value,name=value") # as a user-supplied string
'''
+ # XXXXXXXXX
args_w, kwds_w = args.unpack()
if len(args_w) > 1:
msg = ("set_param() takes at most 1 non-keyword argument, %d given"
Modified: pypy/branch/improve-kwd-args/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/objspace/flow/flowcontext.py (original)
+++ pypy/branch/improve-kwd-args/pypy/objspace/flow/flowcontext.py Mon Oct 12 19:29:24 2009
@@ -397,5 +397,5 @@
class FlowSpaceFrame(pyframe.PyFrame):
def make_arguments(self, nargs):
return ArgumentsForTranslation(self.space, self.peekvalues(nargs))
- def argument_factory(self, arguments, keywords, w_star, w_starstar):
- return ArgumentsForTranslation(self.space, arguments, keywords, w_star, w_starstar)
+ def argument_factory(self, *args):
+ return ArgumentsForTranslation(self.space, *args)
Modified: pypy/branch/improve-kwd-args/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/branch/improve-kwd-args/pypy/objspace/flow/objspace.py (original)
+++ pypy/branch/improve-kwd-args/pypy/objspace/flow/objspace.py Mon Oct 12 19:29:24 2009
@@ -370,7 +370,7 @@
return sc(self, fn, args)
try:
- args_w, kwds_w = args.unpack()
+ args_w, kwds_w = args.copy().unpack()
except UnwrapException:
args_w, kwds_w = '?', '?'
# NOTE: annrpython needs to know about the following two operations!
More information about the Pypy-commit
mailing list