[pypy-svn] r24971 - in pypy/dist/pypy: annotation interpreter interpreter/test
pedronis at codespeak.net
pedronis at codespeak.net
Fri Mar 24 17:33:21 CET 2006
Author: pedronis
Date: Fri Mar 24 17:33:14 2006
New Revision: 24971
Added:
pypy/dist/pypy/interpreter/test/test_argument.py (contents, props changed)
Modified:
pypy/dist/pypy/annotation/annrpython.py
pypy/dist/pypy/annotation/bookkeeper.py
pypy/dist/pypy/annotation/description.py
pypy/dist/pypy/interpreter/argument.py
Log:
(arre, pedronis)
the logic in FunctionDesc.pycall may have discared changes to inputcells done by specialisation
when reparsing the args object. Reconstruct a new args object out of the possibly changed inputcells
instead. Introduced an unmatch_signature helper for this with some tests.
Modified: pypy/dist/pypy/annotation/annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/annrpython.py (original)
+++ pypy/dist/pypy/annotation/annrpython.py Fri Mar 24 17:33:14 2006
@@ -95,6 +95,7 @@
return self.build_graph_types(flowgraph, inputcells)
def annotate_helper(self, function, args_s, policy=None, complete_now=True):
+ args_s = args_s[:]
saved = self.policy, self.added_blocks
if policy is None:
from pypy.annotation.policy import AnnotatorPolicy
Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py (original)
+++ pypy/dist/pypy/annotation/bookkeeper.py Fri Mar 24 17:33:14 2006
@@ -673,7 +673,10 @@
def type(self, item):
return type(item)
-
+
+ def is_true(self, s_tup):
+ assert isinstance(s_tup, SomeTuple)
+ return bool(s_tup.items)
class CallPatternTooComplex(Exception):
pass
Modified: pypy/dist/pypy/annotation/description.py
==============================================================================
--- pypy/dist/pypy/annotation/description.py (original)
+++ pypy/dist/pypy/annotation/description.py Fri Mar 24 17:33:14 2006
@@ -222,8 +222,10 @@
if isinstance(result, FunctionGraph):
graph = result # common case
# if that graph has a different signature, we need to re-parse
- # the arguments
- inputcells = self.parse_arguments(args, graph)
+ # the arguments.
+ # recreate the args object because inputcells may have been changed
+ new_args = args.unmatch_signature(self.signature, inputcells)
+ inputcells = self.parse_arguments(new_args, graph)
result = schedule(graph, inputcells)
# Some specializations may break the invariant of returning
# annotations that are always more general than the previous time.
Modified: pypy/dist/pypy/interpreter/argument.py
==============================================================================
--- pypy/dist/pypy/interpreter/argument.py (original)
+++ pypy/dist/pypy/interpreter/argument.py Fri Mar 24 17:33:14 2006
@@ -82,6 +82,49 @@
self._match_signature(scope_w, argnames, has_vararg, has_kwarg, defaults_w, 0, None)
return scope_w
+ def unmatch_signature(self, signature, data_w):
+ """kind of inverse of match_signature"""
+ args_w, kwds_w = self.unpack()
+ need_cnt = len(args_w)
+ need_kwds = kwds_w.keys()
+ space = self.space
+ argnames, varargname, kwargname = signature
+ cnt = len(argnames)
+ data_args_w = data_w[:cnt]
+ if varargname:
+ data_w_stararg = data_w[cnt]
+ cnt += 1
+ else:
+ data_w_stararg = space.newtuple([])
+
+ unfiltered_kwds_w = {}
+ if kwargname:
+ data_w_starargarg = data_w[cnt]
+ for w_key in space.unpackiterable(data_w_starargarg):
+ key = space.str_w(w_key)
+ w_value = space.getitem(data_w_starargarg, w_key)
+ unfiltered_kwds_w[key] = w_value
+ cnt += 1
+ assert len(data_w) == cnt
+
+ ndata_args_w = len(data_args_w)
+ if ndata_args_w >= need_cnt:
+ args_w = data_args_w[:need_cnt]
+ for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]):
+ unfiltered_kwds_w[argname] = w_arg
+ assert not space.is_true(data_w_stararg)
+ else:
+ args_w = data_args_w[:]
+ for w_stararg in space.unpackiterable(data_w_stararg):
+ args_w.append(w_stararg)
+ assert len(args_w) == need_cnt
+
+ kwds_w = {}
+ for key in need_kwds:
+ kwds_w[key] = unfiltered_kwds_w[key]
+
+ return Arguments(self.space, args_w, kwds_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
Added: pypy/dist/pypy/interpreter/test/test_argument.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/interpreter/test/test_argument.py Fri Mar 24 17:33:14 2006
@@ -0,0 +1,92 @@
+from pypy.interpreter.argument import Arguments
+
+
+class DummySpace(object):
+ def newtuple(self, items):
+ return tuple(items)
+
+ def is_true(self, obj):
+ return bool(obj)
+
+ def unpackiterable(self, it):
+ return list(it)
+
+ def newdict(self, items):
+ return dict(items)
+
+ def setitem(self, obj, key, value):
+ obj[key] = value
+
+ def getitem(self, obj, key):
+ return obj[key]
+
+ def wrap(self, obj):
+ return obj
+
+ def str_w(self, s):
+ return str(s)
+
+ def isinstance(self, obj, cls):
+ return isinstance(obj, cls)
+
+ w_dict = dict
+
+class TestArguments(object):
+
+
+ def test_unmatch_signature(self):
+ space = DummySpace()
+ args = Arguments(space, [1,2,3])
+ sig = (['a', 'b', 'c'], None, None)
+ data = args.match_signature(sig, [])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
+ args = Arguments(space, [1])
+ sig = (['a', 'b', 'c'], None, None)
+ data = args.match_signature(sig, [2, 3])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
+ args = Arguments(space, [1,2,3,4,5])
+ sig = (['a', 'b', 'c'], 'r', None)
+ data = args.match_signature(sig, [])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
+ args = Arguments(space, [1], {'c': 3, 'b': 2})
+ sig = (['a', 'b', 'c'], None, None)
+ data = args.match_signature(sig, [])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
+ args = Arguments(space, [1], {'c': 5})
+ sig = (['a', 'b', 'c'], None, None)
+ data = args.match_signature(sig, [2, 3])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
+ args = Arguments(space, [1], {'c': 5, 'd': 7})
+ sig = (['a', 'b', 'c'], None, 'kw')
+ data = args.match_signature(sig, [2, 3])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
+ args = Arguments(space, [1,2,3,4,5], {'e': 5, 'd': 7})
+ sig = (['a', 'b', 'c'], 'r', 'kw')
+ data = args.match_signature(sig, [2, 3])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
+ args = Arguments(space, [], {}, w_stararg=[1], w_starstararg={'c': 5, 'd': 7})
+ sig = (['a', 'b', 'c'], None, 'kw')
+ data = args.match_signature(sig, [2, 3])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
+ args = Arguments(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])
+ new_args = args.unmatch_signature(sig, data)
+ assert args.unpack() == new_args.unpack()
+
More information about the Pypy-commit
mailing list