Author: Mark Pearse <[email protected]>
Branch: SpecialisedTuples
Changeset: r49114:947ee850430b
Date: 2011-11-10 10:26 +0100
http://bitbucket.org/pypy/pypy/changeset/947ee850430b/
Log: (mwp) store ANY elements wrapped, and fix bug in hash test
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
@@ -4,10 +4,10 @@
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
+from pypy.objspace.std.floatobject import _hash_float
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
@@ -19,10 +19,10 @@
def makespecialisedtuple(space, list_w):
for specialisedClass in unrolling_iterable(_specialisations):
- try:
- return specialisedClass.try_specialisation(space, list_w)
- except NotSpecialised:
- pass
+ try:
+ return specialisedClass.try_specialisation(space, list_w)
+ except NotSpecialised:
+ pass
raise NotSpecialised
class W_SpecialisedTupleObject(W_Object):
@@ -51,7 +51,7 @@
raise NotImplementedError
def unwrap(self, space):
- return tuple(self.tolist)
+ return tuple(self._to_unwrapped_list())
def make_specialised_class(typetuple):
@@ -62,6 +62,7 @@
class cls(W_SpecialisedTupleObject):
def __init__(self, space, values):
+ print cls,cls.__class__, values
assert len(values) == nValues
for i in iter_n:
if typetuple[i] != ANY:
@@ -69,6 +70,7 @@
self.space = space
for i in iter_n:
setattr(self, 'value%s' % i, values[i])
+
@classmethod
def try_specialisation(cls, space, paramlist):
@@ -85,8 +87,6 @@
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
@@ -99,7 +99,7 @@
elif typetuple[i] == str:
unwrappedparams[i] = space.str_w(paramlist[i])
elif typetuple[i] == ANY:
- unwrappedparams[i] = space.unwrap(paramlist[i])#xxx
+ unwrappedparams[i] = paramlist[i]
else:
raise NotSpecialised
return cls(space, unwrappedparams)
@@ -108,15 +108,35 @@
return nValues
def tolist(self):
- return [self.space.wrap(getattr(self, 'value%s' % i)) for i in
iter_n]
+ list_w = [None] * nValues
+ for i in iter_n:
+ if typetuple[i] == ANY:
+ list_w[i] = getattr(self, 'value%s' % i)
+ else:
+ list_w[i] = self.space.wrap(getattr(self, 'value%s' % i))
+ return list_w
+ def _to_unwrapped_list(self):
+ list_w = [None] * nValues
+ for i in iter_n:
+ if typetuple[i] == ANY:
+ list_w[i] = space.unwrap(getattr(self, 'value%s' % i))#xxx
+ else:
+ list_w[i] = getattr(self, 'value%s' % i)
+ return list_w
+
def hash(self, space):
mult = 1000003
x = 0x345678
z = 2
for i in iter_n:
-# y = compute_hash(val)
- y = space.int_w(space.hash(space.wrap(getattr(self, 'value%s'
% i))))
+ value = getattr(self, 'value%s' % i)
+ if typetuple[i] == ANY:
+ y = space.int_w(space.hash(value))
+ elif typetuple[i] == float: # get correct hash for float which
is an integer & other less frequent cases
+ y = _hash_float(space, value)
+ else:
+ y = compute_hash(value)
x = (x ^ y) * mult
z -= 1
mult += 82520 + z + z
@@ -128,9 +148,11 @@
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
+ if not self.space.is_true(self.space.eq(getattr(self,
'value%s' % i), getattr(w_other, 'value%s' % i))):
+ return False
+ else:
+ if getattr(self, 'value%s' % i) != getattr(w_other,
'value%s' % i):
+ return False
else:
return True
@@ -145,7 +167,7 @@
raise FailedToImplement
ncmp = min(self.length(), w_other.length())
for i in iter_n:
- if typetuple[i] == ANY:
+ if typetuple[i] == ANY:#like space.eq on wrapped or two params?
raise FailedToImplement
if ncmp > i:
l_val = getattr(self, 'value%s' % i)
@@ -157,7 +179,10 @@
def getitem(self, index):
for i in iter_n:
if index == i:
- return self.space.wrap(getattr(self, 'value%s' % i))
+ if typetuple[i] == ANY:
+ return getattr(self, 'value%s' % i)
+ else:
+ return self.space.wrap(getattr(self, 'value%s' % i))
raise IndexError
cls.__name__ = 'W_SpecialisedTupleObject' +
''.join([t.__name__.capitalize() for t in typetuple])
@@ -170,6 +195,7 @@
W_SpecialisedTupleObjectIntIntInt = make_specialised_class((int,int,int))
W_SpecialisedTupleObjectFloatFloat = make_specialised_class((float,float))
W_SpecialisedTupleObjectStrStr = make_specialised_class((str, str))
+W_SpecialisedTupleObjectStrAny = make_specialised_class((str, ANY))
W_SpecialisedTupleObjectIntFloatStr= make_specialised_class((int, float, str))
W_SpecialisedTupleObjectIntStrFloatAny= make_specialised_class((int, float,
str, ANY))
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
@@ -23,26 +23,31 @@
def test_specialisedtupleclassname(self):
w_tuple = self.space.newtuple([self.space.wrap(1), self.space.wrap(2)])
assert w_tuple.__class__.__name__ == 'W_SpecialisedTupleObjectIntInt'
+
+ def test_hash_against_normal_tuple(self):
+ N_space = gettestobjspace(**{"objspace.std.withspecialisedtuple":
False})
+ S_space = gettestobjspace(**{"objspace.std.withspecialisedtuple":
True})
- def test_hash_against_normal_tuple(self):
- normalspace = gettestobjspace(**{"objspace.std.withspecialisedtuple":
False})
- specialisedspace =
gettestobjspace(**{"objspace.std.withspecialisedtuple": True})
-
def hash_test(values):
- values_w = [self.space.wrap(value) for value in values]
- w_tuple = normalspace.newtuple(values_w)
- w_specialisedtuple = specialisedspace.newtuple(values_w)
+ 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)
- assert isinstance(w_specialisedtuple, W_SpecialisedTupleObject)
- assert isinstance(w_tuple, W_TupleObject)
- assert not normalspace.is_true(normalspace.eq(w_tuple,
w_specialisedtuple))
- assert specialisedspace.is_true(specialisedspace.eq(w_tuple,
w_specialisedtuple))
- assert
specialisedspace.is_true(specialisedspace.eq(normalspace.hash(w_tuple),
specialisedspace.hash(w_specialisedtuple)))
+ assert isinstance(S_w_tuple, W_SpecialisedTupleObject)
+ assert isinstance(N_w_tuple, W_TupleObject)
+ assert not N_space.is_true(N_space.eq(N_w_tuple, S_w_tuple))
+ 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,()])
def test_setitem(self):
py.test.skip('skip for now, only needed for cpyext')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit