[pypy-commit] pypy SpecialisedTuples: (mwp) also support specialised tuples with 'any' type
mwp
noreply at buildbot.pypy.org
Thu Nov 10 10:48:02 CET 2011
Author: Mark Pearse <mark.pearse at skynet.be>
Branch: SpecialisedTuples
Changeset: r49113:62c0151aba6b
Date: 2011-11-09 13:04 +0100
http://bitbucket.org/pypy/pypy/changeset/62c0151aba6b/
Log: (mwp) also support specialised tuples with 'any' type
diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py
--- a/pypy/objspace/std/specialisedtupleobject.py
+++ b/pypy/objspace/std/specialisedtupleobject.py
@@ -7,16 +7,20 @@
from pypy.rlib.rarithmetic import intmask
from pypy.rlib.objectmodel import compute_hash
from pypy.rlib.unroll import unrolling_iterable
+#from types import NoneType as ANY #deliberately misread this as 'None _specified_'
+
+class ANY(type):
+ pass
class NotSpecialised(Exception):
pass
-
+
_specialisations = []
def makespecialisedtuple(space, list_w):
- for specialisedClass,paramtypes in unrolling_iterable(_specialisations):
+ for specialisedClass in unrolling_iterable(_specialisations):
try:
- return specialisedClass.try_specialisation(space, paramtypes, list_w)
+ return specialisedClass.try_specialisation(space, list_w)
except NotSpecialised:
pass
raise NotSpecialised
@@ -46,40 +50,62 @@
def setitem(self, index, w_item):
raise NotImplementedError
- def unwrap(w_tuple, space):
+ def unwrap(self, space):
return tuple(self.tolist)
def make_specialised_class(typetuple):
assert type(typetuple) == tuple
- iter_n = unrolling_iterable(range(len(typetuple)))
+
+ nValues = len(typetuple)
+ iter_n = unrolling_iterable(range(nValues))
+
class cls(W_SpecialisedTupleObject):
- def __init__(self, space, *values):
- assert len(typetuple) == len(values)
+ def __init__(self, space, values):
+ assert len(values) == nValues
for i in iter_n:
- assert isinstance(values[i], typetuple[i])
+ if typetuple[i] != ANY:
+ assert isinstance(values[i], typetuple[i])
self.space = space
for i in iter_n:
setattr(self, 'value%s' % i, values[i])
@classmethod
- def try_specialisation(specialisedClass, space, paramtypes, paramlist):
-
-
- _w_type_of = {int:space.w_int, float:space.w_float, str:space.w_str}
- _unwrap_as = {int:space.int_w, float:space.float_w, str:space.str_w}
-
-
- if len(paramlist) != len(paramtypes):
+ def try_specialisation(cls, space, paramlist):
+ if len(paramlist) != nValues:
raise NotSpecialised
- for param,paramtype in zip(paramlist, paramtypes):
- if space.type(param) != _w_type_of[paramtype]:
- raise NotSpecialised
- unwrappedparams = [_unwrap_as[paramtype](param) for param,paramtype in zip(paramlist, paramtypes)]
- return specialisedClass(space, *unwrappedparams)
+ for param,val_type in unrolling_iterable(zip(paramlist, typetuple)):
+ if val_type == int:
+ if space.type(param) != space.w_int:
+ raise NotSpecialised
+ elif val_type == float:
+ if space.type(param) != space.w_float:
+ raise NotSpecialised
+ elif val_type == str:
+ if space.type(param) != space.w_str:
+ raise NotSpecialised
+ elif val_type == ANY:
+ if space.type(param) == space.w_type:# else specialise (-1,int) somewhere and unwrap fails
+ raise NotSpecialised
+ pass
+ else:
+ raise NotSpecialised
+ unwrappedparams = [None] * nValues
+ for i in iter_n:
+ if typetuple[i] == int:
+ unwrappedparams[i] = space.int_w(paramlist[i])
+ elif typetuple[i] == float:
+ unwrappedparams[i] = space.float_w(paramlist[i])
+ elif typetuple[i] == str:
+ unwrappedparams[i] = space.str_w(paramlist[i])
+ elif typetuple[i] == ANY:
+ unwrappedparams[i] = space.unwrap(paramlist[i])#xxx
+ else:
+ raise NotSpecialised
+ return cls(space, unwrappedparams)
def length(self):
- return len(typetuple)
+ return nValues
def tolist(self):
return [self.space.wrap(getattr(self, 'value%s' % i)) for i in iter_n]
@@ -101,6 +127,8 @@
if not isinstance(w_other, cls): #so we will be sure we are comparing same types
raise FailedToImplement
for i in iter_n:
+ if typetuple[i] == ANY:
+ raise FailedToImplement
if getattr(self, 'value%s' % i) != getattr(w_other, 'value%s' % i):
return False
else:
@@ -117,6 +145,8 @@
raise FailedToImplement
ncmp = min(self.length(), w_other.length())
for i in iter_n:
+ if typetuple[i] == ANY:
+ raise FailedToImplement
if ncmp > i:
l_val = getattr(self, 'value%s' % i)
r_val = getattr(w_other, 'value%s' % i)
@@ -131,15 +161,17 @@
raise IndexError
cls.__name__ = 'W_SpecialisedTupleObject' + ''.join([t.__name__.capitalize() for t in typetuple])
- _specialisations.append((cls,typetuple))
+ _specialisations.append(cls)
return cls
W_SpecialisedTupleObjectIntInt = make_specialised_class((int,int))
+W_SpecialisedTupleObjectIntAny = make_specialised_class((int, ANY))
W_SpecialisedTupleObjectIntIntInt = make_specialised_class((int,int,int))
W_SpecialisedTupleObjectFloatFloat = make_specialised_class((float,float))
W_SpecialisedTupleObjectStrStr = make_specialised_class((str, str))
W_SpecialisedTupleObjectIntFloatStr= make_specialised_class((int, float, str))
+W_SpecialisedTupleObjectIntStrFloatAny= make_specialised_class((int, float, str, ANY))
registerimplementation(W_SpecialisedTupleObject)
diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py
--- a/pypy/objspace/std/test/test_specialisedtupleobject.py
+++ b/pypy/objspace/std/test/test_specialisedtupleobject.py
@@ -80,8 +80,8 @@
def test_notspecialisedtuple(self):
assert not self.isspecialised((42,43,44,45))
- assert not self.isspecialised((1,1.5))
- assert not self.isspecialised((1,1.0))
+ assert not self.isspecialised((1.5,2))
+ assert not self.isspecialised((1.0,2))
def test_slicing_to_specialised(self):
assert self.isspecialised((1, 2, 3)[0:2])
@@ -175,3 +175,15 @@
assert a[0] == 1 and a[1] == 2.2 and a[2] == '333'
assert a == (1,) + (2.2,) + ('333',)
assert a < (1, 2.2, '334')
+
+ def test_mongrel_with_any(self):
+ a = self.forbid_delegation((1, 2.2, '333',[]))
+ b = (1, 2.2) + ('333', [])
+ if not self.isspecialised(a):
+ skip('my chosen kind of mixed type tuple is not specialised, so skip specific tests on them')
+ assert len(a) == 4
+ assert a[0] == 1 and a[1] == 2.2 and a[2] == '333' and a[3] == []
+ assert a != (1, 2.2, '334', [])
+# assert b == a
+# assert a == (1,) + (2.2,) + ('333',) + ([],)
+# assert a < (1, 2.2, '334', {})
More information about the pypy-commit
mailing list