[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