Author: Armin Rigo <ar...@tunes.org> Branch: SpecialisedTuples Changeset: r50317:5f96cb15c116 Date: 2011-12-08 20:40 +0100 http://bitbucket.org/pypy/pypy/changeset/5f96cb15c116/
Log: - fix space.fixedlist/unpackiterable/listview to handle directly tuples of any kind - fix the test to raise an OperationError, printing nicer tracebacks diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -29,7 +29,7 @@ from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std.smallintobject import W_SmallIntObject from pypy.objspace.std.stringobject import W_StringObject -from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.objspace.std.tupleobject import W_AbstractTupleObject from pypy.objspace.std.typeobject import W_TypeObject # types @@ -391,8 +391,8 @@ self.wrap("expected length %d, got %d" % (expected, got))) def unpackiterable(self, w_obj, expected_length=-1): - if isinstance(w_obj, W_TupleObject): - t = w_obj.wrappeditems[:] + if isinstance(w_obj, W_AbstractTupleObject): + t = w_obj.getitems_copy() elif isinstance(w_obj, W_ListObject): t = w_obj.getitems_copy() else: @@ -405,8 +405,8 @@ def fixedview(self, w_obj, expected_length=-1, unroll=False): """ Fast paths """ - if isinstance(w_obj, W_TupleObject): - t = w_obj.wrappeditems + if isinstance(w_obj, W_AbstractTupleObject): + t = w_obj.tolist() elif isinstance(w_obj, W_ListObject): # XXX this can copy twice t = w_obj.getitems()[:] @@ -428,8 +428,8 @@ def listview(self, w_obj, expected_length=-1): if isinstance(w_obj, W_ListObject): t = w_obj.getitems() - elif isinstance(w_obj, W_TupleObject): - t = w_obj.wrappeditems[:] + elif isinstance(w_obj, W_AbstractTupleObject): + t = w_obj.getitems_copy() else: return ObjSpace.unpackiterable(self, w_obj, expected_length) if expected_length != -1 and len(t) != expected_length: diff --git a/pypy/objspace/std/smalltupleobject.py b/pypy/objspace/std/smalltupleobject.py --- a/pypy/objspace/std/smalltupleobject.py +++ b/pypy/objspace/std/smalltupleobject.py @@ -9,13 +9,14 @@ from pypy.interpreter import gateway from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.unroll import unrolling_iterable +from pypy.tool.sourcetools import func_with_new_name from pypy.objspace.std.tupleobject import W_AbstractTupleObject, W_TupleObject class W_SmallTupleObject(W_AbstractTupleObject): from pypy.objspace.std.tupletype import tuple_typedef as typedef - def tolist(self): - raise NotImplementedError + #def tolist(self): --- inherited from W_AbstractTupleObject + # raise NotImplementedError def length(self): raise NotImplementedError @@ -51,6 +52,9 @@ l[i] = getattr(self, 'w_value%s' % i) return l + # same source code, but builds and returns a resizable list + getitems_copy = func_with_new_name(tolist, 'getitems_copy') + def length(self): return n diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py --- a/pypy/objspace/std/specialisedtupleobject.py +++ b/pypy/objspace/std/specialisedtupleobject.py @@ -8,6 +8,7 @@ from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import compute_hash from pypy.rlib.unroll import unrolling_iterable +from pypy.tool.sourcetools import func_with_new_name class NotSpecialised(Exception): pass @@ -21,8 +22,8 @@ reprlist = [repr(item) for item in self._to_unwrapped_list()] return "%s(%s)" % (self.__class__.__name__, ', '.join(reprlist)) - def tolist(self): - raise NotImplementedError + #def tolist(self): --- inherited from W_AbstractTupleObject + # raise NotImplementedError def _to_unwrapped_list(self): "NOT_RPYTHON" @@ -46,6 +47,9 @@ def unwrap(self, space): return tuple(self._to_unwrapped_list()) + def delegating(self): + pass # for tests only + def make_specialised_class(typetuple): assert type(typetuple) == tuple @@ -84,6 +88,9 @@ list_w[i] = value return list_w + # same source code, but builds and returns a resizable list + getitems_copy = func_with_new_name(tolist, 'getitems_copy') + def _to_unwrapped_list(self): "NOT_RPYTHON" list_w = [None] * nValues @@ -224,6 +231,7 @@ registerimplementation(W_SpecialisedTupleObject) def delegate_SpecialisedTuple2Tuple(space, w_specialised): + w_specialised.delegating() return W_TupleObject(w_specialised.tolist()) def len__SpecialisedTuple(space, w_tuple): diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py --- a/pypy/objspace/std/test/test_specialisedtupleobject.py +++ b/pypy/objspace/std/test/test_specialisedtupleobject.py @@ -63,11 +63,11 @@ def forbid_delegation(space, w_tuple): def delegation_forbidden(): # haaaack - if sys._getframe(2).f_code.co_name == '_mm_repr_tupleS0': - return old_tolist() - raise NotImplementedError, w_tuple - old_tolist = w_tuple.tolist - w_tuple.tolist = delegation_forbidden + co = sys._getframe(2).f_code + if co.co_name.startswith('_mm_repr_tuple'): + return + raise OperationError(space.w_ReferenceError, w_tuple) + w_tuple.delegating = delegation_forbidden return w_tuple cls.w_forbid_delegation = cls.space.wrap(gateway.interp2app(forbid_delegation)) @@ -96,6 +96,10 @@ obj = (1, 2, 3) assert self.isspecialised(obj, '_ooo') + def test_delegation(self): + t = self.forbid_delegation((42, 43)) + raises(ReferenceError, t.__getslice__, 0, 1) + def test_len(self): t = self.forbid_delegation((42,43)) assert len(t) == 2 diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -12,6 +12,15 @@ class W_AbstractTupleObject(W_Object): __slots__ = () + def tolist(self): + "Returns the items, as a fixed-size list." + raise NotImplementedError + + def getitems_copy(self): + "Returns a copy of the items, as a resizable list." + raise NotImplementedError + + class W_TupleObject(W_AbstractTupleObject): from pypy.objspace.std.tupletype import tuple_typedef as typedef _immutable_fields_ = ['wrappeditems[*]'] @@ -29,6 +38,12 @@ items = [space.unwrap(w_item) for w_item in w_tuple.wrappeditems] return tuple(items) + def tolist(self): + return self.wrappeditems + + def getitems_copy(self): + return self.wrappeditems[:] # returns a resizable list + registerimplementation(W_TupleObject) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit