[pypy-svn] r25379 - in pypy/dist/pypy/rpython: ootypesystem ootypesystem/test test
nik at codespeak.net
nik at codespeak.net
Wed Apr 5 15:06:39 CEST 2006
Author: nik
Date: Wed Apr 5 15:06:38 2006
New Revision: 25379
Modified:
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/rlist.py
pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py
pypy/dist/pypy/rpython/test/test_rlist.py
Log:
make recursive data structures involving lists work in ootypesystem.
this involved letting List types fall back to LowLevelType for
__eq__ and __hash__.
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Apr 5 15:06:38 2006
@@ -1,6 +1,6 @@
from pypy.rpython.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char
from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \
- Primitive, isCompatibleType, enforce
+ Primitive, isCompatibleType, enforce, saferecursive
from pypy.rpython.lltypesystem.lltype import frozendict, isCompatibleType
from pypy.tool.uid import uid
@@ -186,19 +186,15 @@
"setitem": Meth([Signed, ITEMTYPE], Void),
})
- def __str__(self):
- return '%s(%s)' % (self.__class__.__name__, self._ITEMTYPE)
-
- def __eq__(self, other):
- if not isinstance(other, List):
- return False
- return self._ITEMTYPE == other._ITEMTYPE
-
- def __ne__(self, other):
- return not (self == other)
+ # NB: We are expecting Lists of the same ITEMTYPE to compare/hash
+ # equal. We don't redefine __eq__/__hash__ since the implementations
+ # from LowLevelType work fine, especially in the face of recursive
+ # data structures. But it is important to make sure that attributes
+ # of supposedly equal Lists compare/hash equal.
- def __hash__(self):
- return hash(self._ITEMTYPE)
+ def __str__(self):
+ return '%s(%s)' % (self.__class__.__name__,
+ saferecursive(str, "...")(self._ITEMTYPE))
def _lookup(self, meth_name):
METH = self._METHODS.get(meth_name)
@@ -214,6 +210,18 @@
def _defl(self):
return self._null
+
+class ForwardReference(OOType):
+ def become(self, real_instance):
+ if not isinstance(real_instance, (Instance, List)):
+ raise TypeError("ForwardReference can only be to an instance, "
+ "not %r" % (real_instance,))
+ self.__class__ = real_instance.__class__
+ self.__dict__ = real_instance.__dict__
+
+ def __hash__(self):
+ raise TypeError("%r object is not hashable" % self.__class__.__name__)
+
# ____________________________________________________________
class _class(object):
@@ -316,6 +324,9 @@
if not isinstance(other, klass):
raise TypeError("comparing an %s with %r" % (klass.__name__, other))
return not other
+
+ def __hash__(self):
+ return hash(self._TYPE)
return mixin
class _null_instance(_null_mixin(_instance), _instance):
Modified: pypy/dist/pypy/rpython/ootypesystem/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rlist.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rlist.py Wed Apr 5 15:06:38 2006
@@ -15,6 +15,7 @@
if not isinstance(item_repr, Repr): # not computed yet, done by setup()
assert callable(item_repr)
self._item_repr_computer = item_repr
+ self.lowleveltype = ootype.ForwardReference()
else:
self.lowleveltype = ootype.List(item_repr.lowleveltype)
self.external_item_repr, self.item_repr = \
@@ -27,7 +28,8 @@
if 'item_repr' not in self.__dict__:
self.external_item_repr, self.item_repr = \
externalvsinternal(self.rtyper, self._item_repr_computer())
- self.lowleveltype = ootype.List(self.item_repr.lowleveltype)
+ if isinstance(self.lowleveltype, ootype.ForwardReference):
+ self.lowleveltype.become(ootype.List(self.item_repr.lowleveltype))
def send_message(self, hop, message, can_raise=False):
v_args = hop.inputargs(self, *hop.args_r[1:])
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py Wed Apr 5 15:06:38 2006
@@ -45,6 +45,20 @@
assert LT1 != LT3
assert hash(LT1) == hash(LT2)
+def test_recursive():
+ FORWARD = ForwardReference()
+ LT = List(FORWARD)
+ FORWARD.become(LT)
+ assert LT == LT
+ assert hash(LT) == hash(LT)
+ str(LT) # make sure this doesn't recurse infinitely
+
+ FORWARD2 = ForwardReference()
+ LT2 = List(FORWARD2)
+ FORWARD2.become(LT2)
+ assert LT == LT2
+ assert hash(LT) == hash(LT2)
+
class TestInterpreted:
def test_append_length(self):
Modified: pypy/dist/pypy/rpython/test/test_rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rlist.py (original)
+++ pypy/dist/pypy/rpython/test/test_rlist.py Wed Apr 5 15:06:38 2006
@@ -215,24 +215,24 @@
res = interpret(dummyfn, [], type_system=self.ts)
assert res == 25
-def test_recursive():
- def dummyfn(N):
- l = []
- while N > 0:
- l = [l]
- N -= 1
- return len(l)
- res = interpret(dummyfn, [5])
- assert res == 1
-
- def dummyfn(N):
- l = []
- while N > 0:
- l.append(l)
- N -= 1
- return len(l)
- res = interpret(dummyfn, [5])
- assert res == 5
+ def test_recursive(self):
+ def dummyfn(N):
+ l = []
+ while N > 0:
+ l = [l]
+ N -= 1
+ return len(l)
+ res = interpret(dummyfn, [5], type_system=self.ts)
+ assert res == 1
+
+ def dummyfn(N):
+ l = []
+ while N > 0:
+ l.append(l)
+ N -= 1
+ return len(l)
+ res = interpret(dummyfn, [5])
+ assert res == 5
def tolst(l):
return map(None, l.ll_items())[:l.ll_length()]
More information about the Pypy-commit
mailing list