[pypy-commit] pypy dynamic-specialized-tuple: Branch to make tuple specialization dynamic

alex_gaynor noreply at buildbot.pypy.org
Tue Mar 13 09:07:14 CET 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: dynamic-specialized-tuple
Changeset: r53424:6c62567f91fb
Date: 2012-03-12 23:12 -0700
http://bitbucket.org/pypy/pypy/changeset/6c62567f91fb/

Log:	Branch to make tuple specialization dynamic

diff --git a/pypy/objspace/std/marshal_impl.py b/pypy/objspace/std/marshal_impl.py
--- a/pypy/objspace/std/marshal_impl.py
+++ b/pypy/objspace/std/marshal_impl.py
@@ -291,7 +291,7 @@
 register(TYPE_STRINGREF, unmarshal_stringref)
 
 def marshal_w__Tuple(space, w_tuple, m):
-    items = w_tuple.wrappeditems
+    items = space.fixedview(w_tuple)
     m.put_tuple_w(TYPE_TUPLE, items)
 
 def unmarshal_Tuple(space, u, tc):
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -15,8 +15,6 @@
     _registered_implementations.add(implcls)
 
 option_to_typename = {
-    "withspecialisedtuple" : ["specialisedtupleobject.W_SpecialisedTupleObject"],
-    "withsmalltuple" : ["smalltupleobject.W_SmallTupleObject"],
     "withsmallint"   : ["smallintobject.W_SmallIntObject"],
     "withsmalllong"  : ["smalllongobject.W_SmallLongObject"],
     "withstrslice"   : ["strsliceobject.W_StringSliceObject"],
@@ -257,15 +255,6 @@
                 (unicodeobject.W_UnicodeObject,
                                        strbufobject.delegate_buf2unicode)
                 ]
-        if config.objspace.std.withsmalltuple:
-            from pypy.objspace.std import smalltupleobject
-            self.typeorder[smalltupleobject.W_SmallTupleObject] += [
-                (tupleobject.W_TupleObject, smalltupleobject.delegate_SmallTuple2Tuple)]
-
-        if config.objspace.std.withspecialisedtuple:
-            from pypy.objspace.std import specialisedtupleobject
-            self.typeorder[specialisedtupleobject.W_SpecialisedTupleObject] += [
-                (tupleobject.W_TupleObject, specialisedtupleobject.delegate_SpecialisedTuple2Tuple)]
 
         # put W_Root everywhere
         self.typeorder[W_Root] = []
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
@@ -392,7 +392,7 @@
 
     def unpackiterable(self, w_obj, expected_length=-1):
         if isinstance(w_obj, W_AbstractTupleObject):
-            t = w_obj.getitems_copy()
+            t = w_obj.getitems_copy(self)
         elif isinstance(w_obj, W_ListObject):
             t = w_obj.getitems_copy()
         else:
@@ -406,7 +406,7 @@
         """ Fast paths
         """
         if isinstance(w_obj, W_AbstractTupleObject):
-            t = w_obj.tolist()
+            t = w_obj.tolist(self)
         elif isinstance(w_obj, W_ListObject):
             if unroll:
                 t = w_obj.getitems_unroll()
diff --git a/pypy/objspace/std/smalltupleobject.py b/pypy/objspace/std/smalltupleobject.py
deleted file mode 100644
--- a/pypy/objspace/std/smalltupleobject.py
+++ /dev/null
@@ -1,161 +0,0 @@
-from pypy.interpreter.error import OperationError
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.inttype import wrapint
-from pypy.objspace.std.multimethod import FailedToImplement
-from pypy.rlib.rarithmetic import intmask
-from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std import slicetype
-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):   --- inherited from W_AbstractTupleObject
-    #    raise NotImplementedError
-
-    def length(self):
-        raise NotImplementedError
-
-    def getitem(self, index):
-        raise NotImplementedError
-
-    def hash(self, space):
-        raise NotImplementedError
-
-    def eq(self, space, w_other):
-        raise NotImplementedError
-
-    def setitem(self, index, w_item):
-        raise NotImplementedError
-
-    def unwrap(w_tuple, space):
-        items = [space.unwrap(w_item) for w_item in w_tuple.tolist()]
-        return tuple(items)
-
-def make_specialized_class(n):
-    iter_n = unrolling_iterable(range(n))
-    class cls(W_SmallTupleObject):
-
-        def __init__(self, values):
-            assert len(values) == n
-            for i in iter_n:
-                setattr(self, 'w_value%s' % i, values[i])
-
-        def tolist(self):
-            l = [None] * n
-            for i in iter_n:
-                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
-
-        def getitem(self, index):
-            for i in iter_n:
-                if index == i:
-                    return getattr(self,'w_value%s' % i)
-            raise IndexError
-
-        def setitem(self, index, w_item):
-            for i in iter_n:
-                if index == i:
-                    setattr(self, 'w_value%s' % i, w_item)
-                    return
-            raise IndexError
-
-        def eq(self, space, w_other):
-            if n != w_other.length():
-                return space.w_False
-            for i in iter_n:
-                item1 = getattr(self,'w_value%s' % i)
-                item2 = w_other.getitem(i)
-                if not space.eq_w(item1, item2):
-                    return space.w_False
-            return space.w_True
-
-        def hash(self, space):
-            mult = 1000003
-            x = 0x345678
-            z = n
-            for i in iter_n:
-                w_item = getattr(self, 'w_value%s' % i)
-                y = space.int_w(space.hash(w_item))
-                x = (x ^ y) * mult
-                z -= 1
-                mult += 82520 + z + z
-            x += 97531
-            return space.wrap(intmask(x))
-
-    cls.__name__ = "W_SmallTupleObject%s" % n
-    return cls
-
-W_SmallTupleObject2 = make_specialized_class(2)
-W_SmallTupleObject3 = make_specialized_class(3)
-W_SmallTupleObject4 = make_specialized_class(4)
-W_SmallTupleObject5 = make_specialized_class(5)
-W_SmallTupleObject6 = make_specialized_class(6)
-W_SmallTupleObject7 = make_specialized_class(7)
-W_SmallTupleObject8 = make_specialized_class(8)
-
-registerimplementation(W_SmallTupleObject)
-
-def delegate_SmallTuple2Tuple(space, w_small):
-    return W_TupleObject(w_small.tolist())
-
-def len__SmallTuple(space, w_tuple):
-    return space.wrap(w_tuple.length())
-
-def getitem__SmallTuple_ANY(space, w_tuple, w_index):
-    index = space.getindex_w(w_index, space.w_IndexError, "tuple index")
-    if index < 0:
-        index += w_tuple.length()
-    try:
-        return w_tuple.getitem(index)
-    except IndexError:
-        raise OperationError(space.w_IndexError,
-                             space.wrap("tuple index out of range"))
-
-def getitem__SmallTuple_Slice(space, w_tuple, w_slice):
-    length = w_tuple.length()
-    start, stop, step, slicelength = w_slice.indices4(space, length)
-    assert slicelength >= 0
-    subitems = [None] * slicelength
-    for i in range(slicelength):
-        subitems[i] = w_tuple.getitem(start)
-        start += step
-    return space.newtuple(subitems)
-
-def mul_smalltuple_times(space, w_tuple, w_times):
-    try:
-        times = space.getindex_w(w_times, space.w_OverflowError)
-    except OperationError, e:
-        if e.match(space, space.w_TypeError):
-            raise FailedToImplement
-        raise
-    if times == 1 and space.type(w_tuple) == space.w_tuple:
-        return w_tuple
-    items = w_tuple.tolist()
-    return space.newtuple(items * times)
-
-def mul__SmallTuple_ANY(space, w_tuple, w_times):
-    return mul_smalltuple_times(space, w_tuple, w_times)
-
-def mul__ANY_SmallTuple(space, w_times, w_tuple):
-    return mul_smalltuple_times(space, w_tuple, w_times)
-
-def eq__SmallTuple_SmallTuple(space, w_tuple1, w_tuple2):
-    return w_tuple1.eq(space, w_tuple2)
-
-def hash__SmallTuple(space, w_tuple):
-    return w_tuple.hash(space)
-
-from pypy.objspace.std import tupletype
-register_all(vars(), tupletype)
diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py
deleted file mode 100644
--- a/pypy/objspace/std/specialisedtupleobject.py
+++ /dev/null
@@ -1,305 +0,0 @@
-from pypy.interpreter.error import OperationError
-from pypy.objspace.std.model import registerimplementation
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.multimethod import FailedToImplement
-from pypy.objspace.std.tupleobject import W_AbstractTupleObject
-from pypy.objspace.std.tupleobject import W_TupleObject
-from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-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
-
-class W_SpecialisedTupleObject(W_AbstractTupleObject):
-    from pypy.objspace.std.tupletype import tuple_typedef as typedef
-    __slots__ = []
-
-    def __repr__(self):
-        """ representation for debugging purposes """
-        reprlist = [repr(item) for item in self._to_unwrapped_list()]
-        return "%s(%s)" % (self.__class__.__name__, ', '.join(reprlist))
-
-    #def tolist(self):   --- inherited from W_AbstractTupleObject
-    #    raise NotImplementedError
-
-    def _to_unwrapped_list(self):
-        "NOT_RPYTHON"
-        raise NotImplementedError
-
-    def length(self):
-        raise NotImplementedError
-
-    def getitem(self, index):
-        raise NotImplementedError
-
-    def hash(self, space):
-        raise NotImplementedError
-
-    def eq(self, space, w_other):
-        raise NotImplementedError
-
-    def setitem(self, index, w_item):
-        raise NotImplementedError
-
-    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
-    
-    nValues = len(typetuple)
-    iter_n = unrolling_iterable(range(nValues))
-    
-    class cls(W_SpecialisedTupleObject):
-        def __init__(self, space, *values_w):
-            self.space = space
-            assert len(values_w) == nValues
-            for i in iter_n:
-                w_obj = values_w[i]
-                val_type = typetuple[i]
-                if val_type == int:
-                    unwrapped = space.int_w(w_obj)
-                elif val_type == float:
-                    unwrapped = space.float_w(w_obj)
-                elif val_type == str:
-                    unwrapped = space.str_w(w_obj)
-                elif val_type == object:
-                    unwrapped = w_obj
-                else:
-                    raise AssertionError
-                setattr(self, 'value%s' % i, unwrapped)
-
-        def length(self):
-            return nValues
-
-        def tolist(self):
-            list_w = [None] * nValues            
-            for i in iter_n:
-                value = getattr(self, 'value%s' % i)
-                if typetuple[i] != object:
-                    value = self.space.wrap(value)
-                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
-            for i in iter_n:
-                value = getattr(self, 'value%s' % i)
-                if typetuple[i] == object:
-                    value = self.space.unwrap(value)
-                list_w[i] = value
-            return list_w
-
-        def hash(self, space):
-            # XXX duplicate logic from tupleobject.py
-            mult = 1000003
-            x = 0x345678
-            z = nValues
-            for i in iter_n:
-                value = getattr(self, 'value%s' % i)
-                if typetuple[i] == object:
-                    y = space.int_w(space.hash(value))
-                elif typetuple[i] == float:
-                    # get the correct hash for float which is an
-                    # integer & other less frequent cases
-                    from pypy.objspace.std.floatobject import _hash_float
-                    y = _hash_float(space, value)
-                else:
-                    y = compute_hash(value)
-                x = (x ^ y) * mult
-                z -= 1
-                mult += 82520 + z + z
-            x += 97531
-            return space.wrap(intmask(x))
-
-        def _eq(self, w_other):
-            if not isinstance(w_other, cls):
-                # if we are not comparing same types, give up
-                raise FailedToImplement
-            for i in iter_n:
-                myval    = getattr(self,    'value%s' % i)
-                otherval = getattr(w_other, 'value%s' % i)
-                if typetuple[i] == object:
-                    if not self.space.eq_w(myval, otherval):
-                        return False
-                else:
-                    if myval != otherval:
-                        return False
-            else:
-                return True
-
-        def eq(self, space, w_other):
-            return space.newbool(self._eq(w_other))
-
-        def ne(self, space, w_other):
-            return space.newbool(not self._eq(w_other))
-
-##        def _compare(self, compare_op, w_other):
-##            if not isinstance(w_other, cls):
-##                raise FailedToImplement
-##            ncmp = min(self.length(), w_other.length())
-##            for i in iter_n:
-##                if typetuple[i] == Any:#like space.eq on wrapped or two params?
-##                    raise FailedToImplement
-##                if ncmp > i:
-##                    l_val = getattr(self, 'value%s' % i)
-##                    r_val = getattr(w_other, 'value%s' % i)
-##                    if l_val != r_val:
-##                        return compare_op(l_val, r_val)
-##            return compare_op(self.length(), w_other.length())
-
-        def getitem(self, index):
-            for i in iter_n:
-                if index == i:
-                    value = getattr(self, 'value%s' % i)
-                    if typetuple[i] != object:
-                        value = self.space.wrap(value)
-                    return value
-            raise IndexError
-
-    cls.__name__ = ('W_SpecialisedTupleObject_' +
-                    ''.join([t.__name__[0] for t in typetuple]))
-    _specialisations.append(cls)
-    return cls
-
-# ---------- current specialized versions ----------
-
-_specialisations = []
-Cls_ii = make_specialised_class((int, int))
-#Cls_is = make_specialised_class((int, str))
-#Cls_io = make_specialised_class((int, object))
-#Cls_si = make_specialised_class((str, int))
-#Cls_ss = make_specialised_class((str, str))
-#Cls_so = make_specialised_class((str, object))
-#Cls_oi = make_specialised_class((object, int))
-#Cls_os = make_specialised_class((object, str))
-Cls_oo = make_specialised_class((object, object))
-Cls_ff = make_specialised_class((float, float))
-#Cls_ooo = make_specialised_class((object, object, object))
-
-def makespecialisedtuple(space, list_w):
-    if len(list_w) == 2:
-        w_arg1, w_arg2 = list_w
-        w_type1 = space.type(w_arg1)
-        #w_type2 = space.type(w_arg2)
-        #
-        if w_type1 is space.w_int:
-            w_type2 = space.type(w_arg2)
-            if w_type2 is space.w_int:
-                return Cls_ii(space, w_arg1, w_arg2)
-            #elif w_type2 is space.w_str:
-            #    return Cls_is(space, w_arg1, w_arg2)
-            #else:
-            #    return Cls_io(space, w_arg1, w_arg2)
-        #
-        #elif w_type1 is space.w_str:
-        #    if w_type2 is space.w_int:
-        #        return Cls_si(space, w_arg1, w_arg2)
-        #    elif w_type2 is space.w_str:
-        #        return Cls_ss(space, w_arg1, w_arg2)
-        #    else:
-        #        return Cls_so(space, w_arg1, w_arg2)
-        #
-        elif w_type1 is space.w_float:
-            w_type2 = space.type(w_arg2)
-            if w_type2 is space.w_float:
-                return Cls_ff(space, w_arg1, w_arg2)
-        #
-        #else:
-        #    if w_type2 is space.w_int:
-        #        return Cls_oi(space, w_arg1, w_arg2)
-        #    elif w_type2 is space.w_str:
-        #        return Cls_os(space, w_arg1, w_arg2)
-        #    else:
-        return Cls_oo(space, w_arg1, w_arg2)
-        #
-    #elif len(list_w) == 3:
-    #    return Cls_ooo(space, list_w[0], list_w[1], list_w[2])
-    else:
-        raise NotSpecialised
-
-# ____________________________________________________________
-
-registerimplementation(W_SpecialisedTupleObject)
-
-def delegate_SpecialisedTuple2Tuple(space, w_specialised):
-    w_specialised.delegating()
-    return W_TupleObject(w_specialised.tolist())
-
-def len__SpecialisedTuple(space, w_tuple):
-    return space.wrap(w_tuple.length())
-
-def getitem__SpecialisedTuple_ANY(space, w_tuple, w_index):
-    index = space.getindex_w(w_index, space.w_IndexError, "tuple index")
-    if index < 0:
-        index += w_tuple.length()
-    try:
-        return w_tuple.getitem(index)
-    except IndexError:
-        raise OperationError(space.w_IndexError,
-                             space.wrap("tuple index out of range"))
-
-def getitem__SpecialisedTuple_Slice(space, w_tuple, w_slice):
-    length = w_tuple.length()
-    start, stop, step, slicelength = w_slice.indices4(space, length)
-    assert slicelength >= 0
-    subitems = [None] * slicelength
-    for i in range(slicelength):
-        subitems[i] = w_tuple.getitem(start)
-        start += step
-    return space.newtuple(subitems)
-
-def mul_specialisedtuple_times(space, w_tuple, w_times):
-    try:
-        times = space.getindex_w(w_times, space.w_OverflowError)
-    except OperationError, e:
-        if e.match(space, space.w_TypeError):
-            raise FailedToImplement
-        raise
-    if times == 1 and space.type(w_tuple) == space.w_tuple:
-        return w_tuple
-    items = w_tuple.tolist()
-    return space.newtuple(items * times)
-
-def mul__SpecialisedTuple_ANY(space, w_tuple, w_times):
-    return mul_specialisedtuple_times(space, w_tuple, w_times)
-
-def mul__ANY_SpecialisedTuple(space, w_times, w_tuple):
-    return mul_specialisedtuple_times(space, w_tuple, w_times)
-
-def eq__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-    return w_tuple1.eq(space, w_tuple2)
-
-def ne__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-    return w_tuple1.ne(space, w_tuple2)
-
-##from operator import lt, le, ge, gt   
- 
-##def lt__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-##    return space.newbool(w_tuple1._compare(lt, w_tuple2))
-
-##def le__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-##    return space.newbool(w_tuple1._compare(le, w_tuple2))
-
-##def ge__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-##    return space.newbool(w_tuple1._compare(ge, w_tuple2))
-
-##def gt__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-##    return space.newbool(w_tuple1._compare(gt, w_tuple2))
-
-def hash__SpecialisedTuple(space, w_tuple):
-    return w_tuple.hash(space)
-
-from pypy.objspace.std import tupletype
-register_all(vars(), tupletype)
diff --git a/pypy/objspace/std/strsliceobject.py b/pypy/objspace/std/strsliceobject.py
--- a/pypy/objspace/std/strsliceobject.py
+++ b/pypy/objspace/std/strsliceobject.py
@@ -18,7 +18,7 @@
 
     def __init__(w_self, str, start, stop):
         assert start >= 0
-        assert stop >= 0 
+        assert stop >= 0
         w_self.str = str
         w_self.start = start
         w_self.stop = stop
@@ -109,7 +109,7 @@
                                       w_self)])
 
 
-def str_count__StringSlice_String_ANY_ANY(space, w_self, w_arg, w_start, w_end): 
+def str_count__StringSlice_String_ANY_ANY(space, w_self, w_arg, w_start, w_end):
     (s, arg, start, end) =  _convert_idx_params(
             space, w_self, w_arg, w_start, w_end)
     return wrapint(space, s.count(arg, start, end))
@@ -150,7 +150,7 @@
     (u_self, _, start, end) = _convert_idx_params(space, w_self,
                                                   space.wrap(''), w_start, w_end)
     for w_suffix in space.fixedview(w_suffixes):
-        suffix = space.str_w(w_suffix) 
+        suffix = space.str_w(w_suffix)
         if stringendswith(u_self, suffix, start, end):
             return space.w_True
     return space.w_False
diff --git a/pypy/objspace/std/test/test_smalltupleobject.py b/pypy/objspace/std/test/test_smalltupleobject.py
deleted file mode 100644
--- a/pypy/objspace/std/test/test_smalltupleobject.py
+++ /dev/null
@@ -1,86 +0,0 @@
-from pypy.objspace.std.tupleobject import W_TupleObject
-from pypy.objspace.std.smalltupleobject import W_SmallTupleObject
-from pypy.interpreter.error import OperationError
-from pypy.objspace.std.test.test_tupleobject import AppTestW_TupleObject
-from pypy.conftest import gettestobjspace
-
-class AppTestW_SmallTupleObject(AppTestW_TupleObject):
-
-    def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withsmalltuple": True})
-        cls.w_issmall = cls.space.appexec([], """():
-            import __pypy__
-            def issmall(obj):
-                assert "SmallTuple" in __pypy__.internal_repr(obj)
-            return issmall
-        """)
-
-    def test_smalltuple(self):
-        self.issmall((1,2))
-        self.issmall((1,2,3))
-
-    def test_slicing_to_small(self):
-        self.issmall((1, 2, 3)[0:2])    # SmallTuple2
-        self.issmall((1, 2, 3)[0:2:1])
-
-        self.issmall((1, 2, 3, 4)[0:3])    # SmallTuple3
-        self.issmall((1, 2, 3, 4)[0:3:1])
-
-    def test_adding_to_small(self):
-        self.issmall((1,)+(2,))       # SmallTuple2
-        self.issmall((1,1)+(2,))      # SmallTuple3
-        self.issmall((1,)+(2,3))
-
-    def test_multiply_to_small(self):
-        self.issmall((1,)*2)
-        self.issmall((1,)*3)
-
-    def test_slicing_from_small(self):
-        assert (1,2)[0:1:1] == (1,)
-        assert (1,2,3)[0:2:1] == (1,2)
-
-    def test_eq(self):
-        a = (1,2,3)
-        b = (1,2,3)
-        assert a == b
-
-        c = (1,3,2)
-        assert a != c
-
-    def test_hash(self):
-        a = (1,2,3)
-        b = (1,2,3)
-        assert hash(a) == hash(b)
-
-        c = (1,3,2)
-        assert hash(a) != hash(c)
-
-class TestW_SmallTupleObject():
-
-    def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withsmalltuple": True})
-
-    def test_issmalltupleobject(self):
-        w_tuple = self.space.newtuple([self.space.wrap(1), self.space.wrap(2)])
-        assert isinstance(w_tuple, W_SmallTupleObject)
-
-    def test_hash_agains_normal_tuple(self):
-        normalspace = gettestobjspace(**{"objspace.std.withsmalltuple": False})
-        w_tuple = normalspace.newtuple([self.space.wrap(1), self.space.wrap(2)])
-
-        smallspace = gettestobjspace(**{"objspace.std.withsmalltuple": True})
-        w_smalltuple = smallspace.newtuple([self.space.wrap(1), self.space.wrap(2)])
-
-        assert isinstance(w_smalltuple, W_SmallTupleObject)
-        assert isinstance(w_tuple, W_TupleObject)
-        assert not normalspace.is_true(normalspace.eq(w_tuple, w_smalltuple))
-        assert smallspace.is_true(smallspace.eq(w_tuple, w_smalltuple))
-        assert smallspace.is_true(smallspace.eq(normalspace.hash(w_tuple), smallspace.hash(w_smalltuple)))
-
-    def test_setitem(self):
-        w_smalltuple = self.space.newtuple([self.space.wrap(1), self.space.wrap(2)])
-        w_smalltuple.setitem(0, self.space.wrap(5))
-        list_w = w_smalltuple.tolist()
-        assert len(list_w) == 2
-        assert self.space.eq_w(list_w[0], self.space.wrap(5))
-        assert self.space.eq_w(list_w[1], self.space.wrap(2))
diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py
deleted file mode 100644
--- a/pypy/objspace/std/test/test_specialisedtupleobject.py
+++ /dev/null
@@ -1,248 +0,0 @@
-import py, sys
-from pypy.objspace.std.tupleobject import W_TupleObject
-from pypy.objspace.std.specialisedtupleobject import W_SpecialisedTupleObject
-from pypy.objspace.std.specialisedtupleobject import _specialisations
-from pypy.interpreter.error import OperationError
-from pypy.conftest import gettestobjspace, option
-from pypy.objspace.std.test import test_tupleobject
-from pypy.interpreter import gateway
-
-
-for cls in _specialisations:
-    globals()[cls.__name__] = cls
-
-
-class TestW_SpecialisedTupleObject():
-
-    def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withspecialisedtuple": True})
-
-    def test_isspecialisedtupleobjectintint(self):
-        w_tuple = self.space.newtuple([self.space.wrap(1), self.space.wrap(2)])
-        assert isinstance(w_tuple, W_SpecialisedTupleObject_ii)
-        
-    def test_isnotspecialisedtupleobject(self):
-        w_tuple = self.space.newtuple([self.space.wrap({})])
-        assert not isinstance(w_tuple, W_SpecialisedTupleObject)
-        
-    def test_specialisedtupleclassname(self):
-        w_tuple = self.space.newtuple([self.space.wrap(1), self.space.wrap(2)])
-        assert w_tuple.__class__.__name__ == 'W_SpecialisedTupleObject_ii'
-
-    def test_hash_against_normal_tuple(self):
-        N_space = gettestobjspace(**{"objspace.std.withspecialisedtuple": False})
-        S_space = gettestobjspace(**{"objspace.std.withspecialisedtuple": True})
-        
-        def hash_test(values, must_be_specialized=True):
-            N_values_w = [N_space.wrap(value) for value in values]
-            S_values_w = [S_space.wrap(value) for value in values]
-            N_w_tuple = N_space.newtuple(N_values_w)
-            S_w_tuple = S_space.newtuple(S_values_w)
-
-            if must_be_specialized:
-                assert isinstance(S_w_tuple, W_SpecialisedTupleObject)
-            assert isinstance(N_w_tuple, W_TupleObject)
-            assert S_space.is_true(S_space.eq(N_w_tuple, S_w_tuple))
-            assert S_space.is_true(S_space.eq(N_space.hash(N_w_tuple), S_space.hash(S_w_tuple)))
-
-        hash_test([1,2])
-        hash_test([1.5,2.8])
-        hash_test([1.0,2.0])
-        hash_test(['arbitrary','strings'])
-        hash_test([1,(1,2,3,4)])
-        hash_test([1,(1,2)])
-        hash_test([1,('a',2)])
-        hash_test([1,()])
-        hash_test([1,2,3], must_be_specialized=False)
-
-
-class AppTestW_SpecialisedTupleObject:
-
-    def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withspecialisedtuple": True})
-        def forbid_delegation(space, w_tuple):
-            def delegation_forbidden():
-                # haaaack
-                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
-        if option.runappdirect:
-            cls.w_forbid_delegation = lambda self, x: x
-            cls.test_delegation = lambda self: skip("runappdirect")
-        else:
-            cls.w_forbid_delegation = cls.space.wrap(
-                gateway.interp2app(forbid_delegation))
-
-    def w_isspecialised(self, obj, expected=''):
-        import __pypy__
-        r = __pypy__.internal_repr(obj)
-        print obj, '==>', r, '   (expected: %r)' % expected
-        return ("SpecialisedTupleObject" + expected) in r
-
-    def test_createspecialisedtuple(self):
-        have = ['ii', 'ff', 'oo']
-        #
-        spec = {int: 'i',
-                float: 'f',
-                str: 's',
-                list: 'o'}
-        #
-        for x in [42, 4.2, "foo", []]:
-            for y in [43, 4.3, "bar", []]:
-                expected1 = spec[type(x)]
-                expected2 = spec[type(y)]
-                if expected1 + expected2 not in have:
-                    expected1 = expected2 = 'o'
-                obj = (x, y)
-                assert self.isspecialised(obj, '_' + expected1 + expected2)
-        #
-        if 'ooo' in have:
-            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
-
-    def test_notspecialisedtuple(self):
-        assert not self.isspecialised((42,43,44,45))
-        assert not self.isspecialised((1.5,))
-
-    def test_slicing_to_specialised(self):
-        t = (1, 2, 3)
-        assert self.isspecialised(t[0:2])
-        t = (1, '2', 3)
-        assert self.isspecialised(t[0:5:2])
-
-    def test_adding_to_specialised(self):
-        t = (1,)
-        assert self.isspecialised(t + (2,))
-
-    def test_multiply_to_specialised(self):
-        t = (1,)
-        assert self.isspecialised(t * 2)
-
-    def test_slicing_from_specialised(self):
-        t = (1, 2, 3)
-        assert t[0:2:1] == (1, 2)
-
-    def test_eq_no_delegation(self):
-        t = (1,)
-        a = self.forbid_delegation(t + (2,))
-        b = (1, 2)
-        assert a == b
-
-        c = (2, 1)
-        assert not a == c
-
-    def test_eq_can_delegate(self):        
-        a = (1,2)
-        b = (1,3,2)
-        assert not a == b
-
-        values = [2, 2L, 2.0, 1, 1L, 1.0]
-        for x in values:
-            for y in values:
-                assert ((1,2) == (x,y)) == (1 == x and 2 == y)
-
-    def test_neq(self):
-        a = self.forbid_delegation((1,2))
-        b = (1,)
-        b = b+(2,)
-        assert not a != b
-        
-        c = (1,3)
-        assert a != c
-        
-    def test_ordering(self):
-        a = (1,2) #self.forbid_delegation((1,2)) --- code commented out
-        assert a <  (2,2)    
-        assert a <  (1,3)    
-        assert not a <  (1,2) 
-
-        assert a <=  (2,2)    
-        assert a <=  (1,2) 
-        assert not a <=  (1,1) 
-           
-        assert a >= (0,2)    
-        assert a >= (1,2)    
-        assert not a >= (1,3)    
-        
-        assert a > (0,2)    
-        assert a > (1,1)    
-        assert not a > (1,3)    
-
-        assert (2,2) > a
-        assert (1,3) > a
-        assert not (1,2) > a
-           
-        assert (2,2) >= a
-        assert (1,2) >= a
-        assert not (1,1) >= a
-           
-        assert (0,2) <= a
-        assert (1,2) <= a
-        assert not (1,3) <= a
-        
-        assert (0,2) < a
-        assert (1,1) < a
-        assert not (1,3) < a
-
-    def test_hash(self):
-        a = (1,2)
-        b = (1,)
-        b += (2,) # else a and b refer to same constant
-        assert hash(a) == hash(b)
-
-        c = (2,4)
-        assert hash(a) != hash(c)
-
-        assert hash(a) == hash((1L, 2L)) == hash((1.0, 2.0)) == hash((1.0, 2L))
-
-    def test_getitem(self):
-        t = self.forbid_delegation((5,3))
-        assert (t)[0] == 5
-        assert (t)[1] == 3
-        assert (t)[-1] == 3
-        assert (t)[-2] == 5
-        raises(IndexError, "t[2]")
-        raises(IndexError, "t[-3]")
-
-    def test_three_tuples(self):
-        if not self.isspecialised((1, 2, 3)):
-            skip("don't have specialization for 3-tuples")
-        b = self.forbid_delegation((1, 2, 3))
-        c = (1,)
-        d = c + (2, 3)
-        assert self.isspecialised(d)
-        assert b == d
-
-    def test_mongrel(self):
-        a = self.forbid_delegation((2.2, '333'))
-        assert self.isspecialised(a)
-        assert len(a) == 2
-        assert a[0] == 2.2 and a[1] == '333'
-        b = ('333',)
-        assert a == (2.2,) + b
-        assert not a != (2.2,) + b
-        #
-        if not self.isspecialised((1, 2, 3)):
-            skip("don't have specialization for 3-tuples")
-        a = self.forbid_delegation((1, 2.2, '333'))
-        assert self.isspecialised(a)
-        assert len(a) == 3
-        assert a[0] == 1 and a[1] == 2.2 and a[2] == '333'
-        b = ('333',)
-        assert a == (1, 2.2,) + b
-        assert not a != (1, 2.2) + b
-
-
-class AppTestAll(test_tupleobject.AppTestW_TupleObject):
-    pass
diff --git a/pypy/objspace/std/test/test_tupleobject.py b/pypy/objspace/std/test/test_tupleobject.py
--- a/pypy/objspace/std/test/test_tupleobject.py
+++ b/pypy/objspace/std/test/test_tupleobject.py
@@ -1,238 +1,6 @@
 #from __future__ import nested_scopes
-from pypy.objspace.std.tupleobject import W_TupleObject
 from pypy.interpreter.error import OperationError
 
-class TestW_TupleObject:
-
-    def test_is_true(self):
-        w = self.space.wrap
-        w_tuple = W_TupleObject([])
-        assert self.space.is_true(w_tuple) == False
-        w_tuple = W_TupleObject([w(5)])
-        assert self.space.is_true(w_tuple) == True
-        w_tuple = W_TupleObject([w(5), w(3)])
-        assert self.space.is_true(w_tuple) == True
-
-    def test_len(self):
-        w = self.space.wrap
-        w_tuple = W_TupleObject([])
-        assert self.space.eq_w(self.space.len(w_tuple), w(0))
-        w_tuple = W_TupleObject([w(5)])
-        assert self.space.eq_w(self.space.len(w_tuple), w(1))
-        w_tuple = W_TupleObject([w(5), w(3), w(99)]*111)
-        assert self.space.eq_w(self.space.len(w_tuple), w(333))
-
-    def test_getitem(self):
-        w = self.space.wrap
-        w_tuple = W_TupleObject([w(5), w(3)])
-        assert self.space.eq_w(self.space.getitem(w_tuple, w(0)), w(5))
-        assert self.space.eq_w(self.space.getitem(w_tuple, w(1)), w(3))
-        assert self.space.eq_w(self.space.getitem(w_tuple, w(-2)), w(5))
-        assert self.space.eq_w(self.space.getitem(w_tuple, w(-1)), w(3))
-        self.space.raises_w(self.space.w_IndexError,
-                            self.space.getitem, w_tuple, w(2))
-        self.space.raises_w(self.space.w_IndexError,
-                            self.space.getitem, w_tuple, w(42))
-        self.space.raises_w(self.space.w_IndexError,
-                            self.space.getitem, w_tuple, w(-3))
-
-    def test_iter(self):
-        w = self.space.wrap
-        w_tuple = W_TupleObject([w(5), w(3), w(99)])
-        w_iter = self.space.iter(w_tuple)
-        assert self.space.eq_w(self.space.next(w_iter), w(5))
-        assert self.space.eq_w(self.space.next(w_iter), w(3))
-        assert self.space.eq_w(self.space.next(w_iter), w(99))
-        raises(OperationError, self.space.next, w_iter)
-        raises(OperationError, self.space.next, w_iter)
-
-    def test_contains(self):
-        w = self.space.wrap
-        w_tuple = W_TupleObject([w(5), w(3), w(99)])
-        assert self.space.eq_w(self.space.contains(w_tuple, w(5)),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.contains(w_tuple, w(99)),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.contains(w_tuple, w(11)),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.contains(w_tuple, w_tuple),
-                           self.space.w_False)
-
-    def test_add(self):
-        w = self.space.wrap
-        w_tuple0 = W_TupleObject([])
-        w_tuple1 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple2 = W_TupleObject([w(-7)] * 111)
-        assert self.space.eq_w(self.space.add(w_tuple1, w_tuple1),
-                           W_TupleObject([w(5), w(3), w(99),
-                                                      w(5), w(3), w(99)]))
-        assert self.space.eq_w(self.space.add(w_tuple1, w_tuple2),
-                           W_TupleObject([w(5), w(3), w(99)] + [w(-7)] * 111))
-        assert self.space.eq_w(self.space.add(w_tuple1, w_tuple0), w_tuple1)
-        assert self.space.eq_w(self.space.add(w_tuple0, w_tuple2), w_tuple2)
-
-    def test_mul(self):
-        # only testing right mul at the moment
-        w = self.space.wrap
-        arg = w(2)
-        n = 3
-        w_tup = W_TupleObject([arg])
-        w_tup3 = W_TupleObject([arg]*n)
-        w_res = self.space.mul(w_tup, w(n))
-        assert self.space.eq_w(w_tup3, w_res)
-        # commute
-        w_res = self.space.mul(w(n), w_tup)
-        assert self.space.eq_w(w_tup3, w_res)
-        # check tuple*1 is identity (optimisation tested by CPython tests)
-        w_res = self.space.mul(w_tup, w(1))
-        assert w_res is w_tup
-
-    def test_getslice(self):
-        w = self.space.wrap
-
-        def test1(testtuple, start, stop, step, expected):
-            w_slice  = self.space.newslice(w(start), w(stop), w(step))
-            w_tuple = W_TupleObject([w(i) for i in testtuple])
-            w_result = self.space.getitem(w_tuple, w_slice)
-            assert self.space.unwrap(w_result) == expected
-        
-        for testtuple in [(), (5,3,99), tuple(range(5,555,10))]:
-            for start in [-2, -1, 0, 1, 10]:
-                for end in [-1, 0, 2, 999]:
-                    test1(testtuple, start, end, 1, testtuple[start:end])
-
-        test1((5,7,1,4), 3, 1, -2,  (4,))
-        test1((5,7,1,4), 3, 0, -2,  (4, 7))
-        test1((5,7,1,4), 3, -1, -2, ())
-        test1((5,7,1,4), -2, 11, 2, (1,))
-        test1((5,7,1,4), -3, 11, 2, (7, 4))
-        test1((5,7,1,4), -5, 11, 2, (5, 1))
-
-    def test_eq(self):
-        w = self.space.wrap
-        
-        w_tuple0 = W_TupleObject([])
-        w_tuple1 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple2 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple3 = W_TupleObject([w(5), w(3), w(99), w(-1)])
-
-        assert self.space.eq_w(self.space.eq(w_tuple0, w_tuple1),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.eq(w_tuple1, w_tuple0),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.eq(w_tuple1, w_tuple1),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.eq(w_tuple1, w_tuple2),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.eq(w_tuple2, w_tuple3),
-                           self.space.w_False)
-    def test_ne(self):
-        w = self.space.wrap
-        
-        w_tuple0 = W_TupleObject([])
-        w_tuple1 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple2 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple3 = W_TupleObject([w(5), w(3), w(99), w(-1)])
-
-        assert self.space.eq_w(self.space.ne(w_tuple0, w_tuple1),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.ne(w_tuple1, w_tuple0),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.ne(w_tuple1, w_tuple1),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.ne(w_tuple1, w_tuple2),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.ne(w_tuple2, w_tuple3),
-                           self.space.w_True)
-    def test_lt(self):
-        w = self.space.wrap
-        
-        w_tuple0 = W_TupleObject([])
-        w_tuple1 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple2 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple3 = W_TupleObject([w(5), w(3), w(99), w(-1)])
-        w_tuple4 = W_TupleObject([w(5), w(3), w(9), w(-1)])
-
-        assert self.space.eq_w(self.space.lt(w_tuple0, w_tuple1),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.lt(w_tuple1, w_tuple0),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.lt(w_tuple1, w_tuple1),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.lt(w_tuple1, w_tuple2),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.lt(w_tuple2, w_tuple3),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.lt(w_tuple4, w_tuple3),
-                           self.space.w_True)
-        
-    def test_ge(self):
-        w = self.space.wrap
-        
-        w_tuple0 = W_TupleObject([])
-        w_tuple1 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple2 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple3 = W_TupleObject([w(5), w(3), w(99), w(-1)])
-        w_tuple4 = W_TupleObject([w(5), w(3), w(9), w(-1)])
-
-        assert self.space.eq_w(self.space.ge(w_tuple0, w_tuple1),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.ge(w_tuple1, w_tuple0),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.ge(w_tuple1, w_tuple1),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.ge(w_tuple1, w_tuple2),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.ge(w_tuple2, w_tuple3),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.ge(w_tuple4, w_tuple3),
-                           self.space.w_False)
-        
-    def test_gt(self):
-        w = self.space.wrap
-        
-        w_tuple0 = W_TupleObject([])
-        w_tuple1 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple2 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple3 = W_TupleObject([w(5), w(3), w(99), w(-1)])
-        w_tuple4 = W_TupleObject([w(5), w(3), w(9), w(-1)])
-
-        assert self.space.eq_w(self.space.gt(w_tuple0, w_tuple1),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.gt(w_tuple1, w_tuple0),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.gt(w_tuple1, w_tuple1),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.gt(w_tuple1, w_tuple2),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.gt(w_tuple2, w_tuple3),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.gt(w_tuple4, w_tuple3),
-                           self.space.w_False)
-        
-    def test_le(self):
-        w = self.space.wrap
-        
-        w_tuple0 = W_TupleObject([])
-        w_tuple1 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple2 = W_TupleObject([w(5), w(3), w(99)])
-        w_tuple3 = W_TupleObject([w(5), w(3), w(99), w(-1)])
-        w_tuple4 = W_TupleObject([w(5), w(3), w(9), w(-1)])
-
-        assert self.space.eq_w(self.space.le(w_tuple0, w_tuple1),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.le(w_tuple1, w_tuple0),
-                           self.space.w_False)
-        assert self.space.eq_w(self.space.le(w_tuple1, w_tuple1),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.le(w_tuple1, w_tuple2),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.le(w_tuple2, w_tuple3),
-                           self.space.w_True)
-        assert self.space.eq_w(self.space.le(w_tuple4, w_tuple3),
-                           self.space.w_True)
-
-
 class AppTestW_TupleObject:
 
     def test_is_true(self):
@@ -243,7 +11,7 @@
     def test_len(self):
         assert len(()) == 0
         assert len((5,)) == 1
-        assert len((5,3,99,1,2,3,4,5,6)) == 9 
+        assert len((5,3,99,1,2,3,4,5,6)) == 9
 
     def test_getitem(self):
         assert (5,3)[0] == 5
@@ -348,3 +116,61 @@
         assert (4, 2, 3, 4).index(4, 1) == 3
         assert (4, 4, 4).index(4, 1, 2) == 1
         raises(ValueError, (1, 2, 3, 4).index, 4, 0, 2)
+
+
+class AppTest_SpecializedTuple(object):
+    def test_ints(self):
+        t = (1, 2, 3)
+        assert self.get_specialization(t) == (int, int, int)
+
+    def test_floats(self):
+        t = (1.1, 1.1, 2.2)
+        assert self.get_specialization(t) == (float, float, float)
+
+    def test_bools(self):
+        t = (True, False)
+        assert self.get_specialization(t) == (bool, bool)
+
+    def test_strs(self):
+        t = ("a", "b", "c")
+        assert self.get_specialization(t) == (str, str, str)
+
+    def test_mixed(self):
+        t = (1, True, "a")
+        assert self.get_specialization(t) == (int, bool, str)
+
+    def test_add(self):
+        t = (1,)
+        assert self.get_specialization(t) == (int,)
+        t = t + t
+        assert self.get_specialization(t) == (int, int)
+
+    def test_mul(self):
+        t = (1,) * 3
+        assert self.get_specialization(t) == (int, int, int)
+
+    def test_length(self):
+        t = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
+        assert self.get_specialization(t) is None
+
+        t = (1,) * 10
+        assert self.get_specialization(t) is None
+
+        t = (1,) * 7 + (True,)
+        assert self.get_specialization(t) is None
+
+    def test_object(self):
+        t = (1, True, object())
+        assert self.get_specialization(t) == (int, bool, object)
+
+    def test_specialization(self):
+        t = (1,)
+        assert self.same_specialization(t, t)
+
+        s = (1, 1)
+        t *= 2
+        assert self.same_specialization(s, t)
+
+        t = (1,) * 10
+        s = (1,) * 9
+        assert self.same_specialization(s, t)
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,187 +12,172 @@
 class W_AbstractTupleObject(W_Object):
     __slots__ = ()
 
-    def tolist(self):
+    def tolist(self, space):
         "Returns the items, as a fixed-size list."
         raise NotImplementedError
 
-    def getitems_copy(self):
+    def getitems_copy(self, space):
         "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[*]']
 
-    def __init__(w_self, wrappeditems):
-        make_sure_not_resized(wrappeditems)
-        w_self.wrappeditems = wrappeditems   # a list of wrapped values
+    def __init__(self, shape, items):
+        self.shape = shape
+        self.items = items
 
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        reprlist = [repr(w_item) for w_item in w_self.wrappeditems]
-        return "%s(%s)" % (w_self.__class__.__name__, ', '.join(reprlist))
+    def tolist(self, space):
+        items_w = [None] * self.length()
+        for i in xrange(self.length()):
+            items_w[i] = self.getitem(space, i)
+        return items_w
 
-    def unwrap(w_tuple, space):
-        items = [space.unwrap(w_item) for w_item in w_tuple.wrappeditems]
-        return tuple(items)
+    def getitems_copy(self, space):
+        return self.tolist(space)
 
-    def tolist(self):
-        return self.wrappeditems
+    def length(self):
+        return self.shape.length(self.items)
 
-    def getitems_copy(self):
-        return self.wrappeditems[:]   # returns a resizable list
+    def getitem(self, space, i):
+        return self.shape.getitem(space, self.items, i)
+
+
+class BaseShapeType(object):
+    def wrap(self, space, items, i):
+        raise NotImplementedError
+
+class ObjectShapeType(BaseShapeType):
+    def getitem(self, space, items, i):
+        return items[i]
+
+class BaseShape(object):
+    pass
+
+class Shape(BaseShape):
+    def __init__(self, shapetypes):
+        self.shapetypes = shapetypes
+
+    def length(self, items):
+        return len(self.shapetypes)
+
+    def getitem(self, space, items, i):
+        return self.shapetypes[i].getitem(space, items, i)
+
+class LargeShape(BaseShape):
+    def length(self, items):
+        return len(items)
+
+    def getitem(self, space, items, i):
+        return items[i]
+
+class ShapeCache(object):
+    def __init__(self, space):
+        self._shapes = {}
+        self.large_shape = LargeShape()
+        self.object_shapetype = ObjectShapeType()
+
+    def find_shape(self, types):
+        return self._shapes.setdefault(tuple(types), Shape(types))
+
+def get_shape_cache(space):
+    return space.fromcache(ShapeCache)
+
 
 registerimplementation(W_TupleObject)
 
 
 def len__Tuple(space, w_tuple):
-    result = len(w_tuple.wrappeditems)
-    return wrapint(space, result)
+    return space.wrap(w_tuple.length())
 
 def getitem__Tuple_ANY(space, w_tuple, w_index):
-    # getindex_w should get a second argument space.w_IndexError,
-    # but that doesn't exist the first time this is called.
-    try:
-        w_IndexError = space.w_IndexError
-    except AttributeError:
-        w_IndexError = None
-    index = space.getindex_w(w_index, w_IndexError, "tuple index")
-    try:
-        return w_tuple.wrappeditems[index]
-    except IndexError:
+    index = space.getindex_w(w_index, space.w_IndexError, "tuple index")
+    if index < 0:
+        index += w_tuple.length()
+    if not (0 <= index < w_tuple.length()):
         raise OperationError(space.w_IndexError,
                              space.wrap("tuple index out of range"))
+    return w_tuple.getitem(space, index)
 
 def getitem__Tuple_Slice(space, w_tuple, w_slice):
-    items = w_tuple.wrappeditems
-    length = len(items)
+    length = w_tuple.length()
     start, stop, step, slicelength = w_slice.indices4(space, length)
     assert slicelength >= 0
     subitems = [None] * slicelength
     for i in range(slicelength):
-        subitems[i] = items[start]
+        subitems[i] = w_tuple.getitem(space, start)
         start += step
     return space.newtuple(subitems)
 
-def getslice__Tuple_ANY_ANY(space, w_tuple, w_start, w_stop):
-    length = len(w_tuple.wrappeditems)
-    start, stop = normalize_simple_slice(space, length, w_start, w_stop)
-    return space.newtuple(w_tuple.wrappeditems[start:stop])
-
 def contains__Tuple_ANY(space, w_tuple, w_obj):
-    for w_item in w_tuple.wrappeditems:
-        if space.eq_w(w_item, w_obj):
+    for i in xrange(w_tuple.length()):
+        if space.eq_w(w_tuple.getitem(space, i), w_obj):
             return space.w_True
     return space.w_False
 
-def iter__Tuple(space, w_tuple):
-    from pypy.objspace.std import iterobject
-    return iterobject.W_FastTupleIterObject(w_tuple, w_tuple.wrappeditems)
+def add__Tuple_Tuple(space, w_tuple1, w_tuple2):
+    return space.newtuple(w_tuple1.tolist(space) + w_tuple2.tolist(space))
 
-def add__Tuple_Tuple(space, w_tuple1, w_tuple2):
-    items1 = w_tuple1.wrappeditems
-    items2 = w_tuple2.wrappeditems
-    return space.newtuple(items1 + items2)
-
-def mul_tuple_times(space, w_tuple, w_times):
+def mul__Tuple_ANY(space, w_tuple, w_times):
     try:
         times = space.getindex_w(w_times, space.w_OverflowError)
     except OperationError, e:
         if e.match(space, space.w_TypeError):
             raise FailedToImplement
         raise
-    if times == 1 and space.type(w_tuple) == space.w_tuple:
+    if times == 1 and space.type(w_tuple) is space.w_tuple:
         return w_tuple
-    items = w_tuple.wrappeditems
-    return space.newtuple(items * times)
-
-def mul__Tuple_ANY(space, w_tuple, w_times):
-    return mul_tuple_times(space, w_tuple, w_times)
+    return space.newtuple(w_tuple.tolist(space) * times)
 
 def mul__ANY_Tuple(space, w_times, w_tuple):
-    return mul_tuple_times(space, w_tuple, w_times)
+    pass
 
 def eq__Tuple_Tuple(space, w_tuple1, w_tuple2):
-    items1 = w_tuple1.wrappeditems
-    items2 = w_tuple2.wrappeditems
-    if len(items1) != len(items2):
+    if w_tuple1.shape is not w_tuple2.shape:
         return space.w_False
-    for i in range(len(items1)):
-        item1 = items1[i]
-        item2 = items2[i]
-        if not space.eq_w(item1, item2):
+    if w_tuple1.length() != w_tuple2.length():
+        return space.w_False
+    for i in xrange(w_tuple1.length()):
+        if not space.eq_w(w_tuple1.getitem(space, i), w_tuple2.getitem(space, i)):
             return space.w_False
     return space.w_True
 
 def lt__Tuple_Tuple(space, w_tuple1, w_tuple2):
-    items1 = w_tuple1.wrappeditems
-    items2 = w_tuple2.wrappeditems
-    ncmp = min(len(items1), len(items2))
-    # Search for the first index where items are different
-    for p in range(ncmp):
-        if not space.eq_w(items1[p], items2[p]):
-            return space.lt(items1[p], items2[p])
-    # No more items to compare -- compare sizes
-    return space.newbool(len(items1) < len(items2))
+    pass
 
 def gt__Tuple_Tuple(space, w_tuple1, w_tuple2):
-    items1 = w_tuple1.wrappeditems
-    items2 = w_tuple2.wrappeditems
-    ncmp = min(len(items1), len(items2))
-    # Search for the first index where items are different
-    for p in range(ncmp):
-        if not space.eq_w(items1[p], items2[p]):
-            return space.gt(items1[p], items2[p])
-    # No more items to compare -- compare sizes
-    return space.newbool(len(items1) > len(items2))
+    pass
 
 def repr__Tuple(space, w_tuple):
-    items = w_tuple.wrappeditems
-    # XXX this is quite innefficient, still better than calling
-    #     it via applevel
-    if len(items) == 1:
-        return space.wrap("(" + space.str_w(space.repr(items[0])) + ",)")
-    return space.wrap("(" +
-                 (", ".join([space.str_w(space.repr(item)) for item in items]))
-                      + ")")
+    pass
 
-def hash__Tuple(space, w_tuple):
-    return space.wrap(hash_tuple(space, w_tuple.wrappeditems))
-
-def hash_tuple(space, wrappeditems):
+def hash_items(space, w_tuple):
     # this is the CPython 2.4 algorithm (changed from 2.3)
     mult = 1000003
     x = 0x345678
-    z = len(wrappeditems)
-    for w_item in wrappeditems:
-        y = space.hash_w(w_item)
+    z = w_tuple.length()
+    for i in xrange(z):
+        y = space.hash_w(w_tuple.getitem(space, i))
         x = (x ^ y) * mult
         z -= 1
         mult += 82520 + z + z
     x += 97531
     return intmask(x)
 
+def hash__Tuple(space, w_tuple):
+    return space.wrap(hash_items(space, w_tuple))
+
+def hash_tuple(space, wrappeditems):
+    pass
+
 def getnewargs__Tuple(space, w_tuple):
-    return space.newtuple([space.newtuple(w_tuple.wrappeditems)])
+    pass
 
 def tuple_count__Tuple_ANY(space, w_tuple, w_obj):
-    count = 0
-    for w_item in w_tuple.wrappeditems:
-        if space.eq_w(w_item, w_obj):
-            count += 1
-    return space.wrap(count)
+    pass
 
 def tuple_index__Tuple_ANY_ANY_ANY(space, w_tuple, w_obj, w_start, w_stop):
-    length = len(w_tuple.wrappeditems)
-    start, stop = slicetype.unwrap_start_stop(space, length, w_start, w_stop)
-    for i in range(start, min(stop, length)):
-        w_item = w_tuple.wrappeditems[i]
-        if space.eq_w(w_item, w_obj):
-            return space.wrap(i)
-    raise OperationError(space.w_ValueError,
-                         space.wrap("tuple.index(x): x not in tuple"))
+    pass
 
 from pypy.objspace.std import tupletype
 register_all(vars(), tupletype)
diff --git a/pypy/objspace/std/tupletype.py b/pypy/objspace/std/tupletype.py
--- a/pypy/objspace/std/tupletype.py
+++ b/pypy/objspace/std/tupletype.py
@@ -3,39 +3,32 @@
 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
 
+
+MAXIMUM_SPECIALIZED_SIZE = 8
+
 def wraptuple(space, list_w):
     from pypy.objspace.std.tupleobject import W_TupleObject
 
-    if space.config.objspace.std.withspecialisedtuple:
-        from specialisedtupleobject import makespecialisedtuple, NotSpecialised
-        try:
-            return makespecialisedtuple(space, list_w)
-        except NotSpecialised:
-            pass
+    w_tuple = space.allocate_instance(W_TupleObject, space.w_tuple)
+    make_tuple(space, w_tuple, list_w)
+    return w_tuple
 
-    if space.config.objspace.std.withsmalltuple:
-        from pypy.objspace.std.smalltupleobject import W_SmallTupleObject2
-        from pypy.objspace.std.smalltupleobject import W_SmallTupleObject3
-        from pypy.objspace.std.smalltupleobject import W_SmallTupleObject4
-        from pypy.objspace.std.smalltupleobject import W_SmallTupleObject5
-        from pypy.objspace.std.smalltupleobject import W_SmallTupleObject6
-        from pypy.objspace.std.smalltupleobject import W_SmallTupleObject7
-        from pypy.objspace.std.smalltupleobject import W_SmallTupleObject8
-        if len(list_w) == 2:
-            return W_SmallTupleObject2(list_w)
-        if len(list_w) == 3:
-            return W_SmallTupleObject3(list_w)
-        if len(list_w) == 4:
-            return W_SmallTupleObject4(list_w)
-        if len(list_w) == 5:
-            return W_SmallTupleObject5(list_w)
-        if len(list_w) == 6:
-            return W_SmallTupleObject6(list_w)
-        if len(list_w) == 7:
-            return W_SmallTupleObject7(list_w)
-        if len(list_w) == 8:
-            return W_SmallTupleObject8(list_w)
-    return W_TupleObject(list_w)
+def make_tuple(space, w_tuple, list_w):
+    from pypy.objspace.std.tupleobject import W_TupleObject, get_shape_cache
+
+    cache = get_shape_cache(space)
+    if len(list_w) > MAXIMUM_SPECIALIZED_SIZE:
+        W_TupleObject.__init__(w_tuple, cache.large_shape, list_w)
+    else:
+        types = []
+        items = []
+        for w_item in list_w:
+            types.append(cache.object_shapetype)
+            items.append(w_item)
+
+        shape = cache.find_shape(types)
+        W_TupleObject.__init__(w_tuple, shape, items)
+        return W_TupleObject(shape, items)
 
 tuple_count = SMM("count", 2,
                   doc="count(obj) -> number of times obj appears in the tuple")
@@ -47,6 +40,7 @@
 
 def descr__new__(space, w_tupletype, w_sequence=gateway.NoneNotWrapped):
     from pypy.objspace.std.tupleobject import W_TupleObject
+
     if w_sequence is None:
         tuple_w = []
     elif (space.is_w(w_tupletype, space.w_tuple) and
@@ -55,7 +49,7 @@
     else:
         tuple_w = space.fixedview(w_sequence)
     w_obj = space.allocate_instance(W_TupleObject, w_tupletype)
-    W_TupleObject.__init__(w_obj, tuple_w)
+    make_tuple(space, w_obj, tuple_w)
     return w_obj
 
 # ____________________________________________________________


More information about the pypy-commit mailing list