Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit