[pypy-svn] r22900 - in pypy/dist/pypy/rpython/lltypesystem: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Tue Jan 31 15:38:30 CET 2006
Author: cfbolz
Date: Tue Jan 31 15:38:29 2006
New Revision: 22900
Added:
pypy/dist/pypy/rpython/lltypesystem/test/test_picklelltype.py
Modified:
pypy/dist/pypy/rpython/lltypesystem/lltype.py
Log:
make some of the classes in lltype pickleable
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Tue Jan 31 15:38:29 2006
@@ -1,9 +1,9 @@
-import weakref
import py
from pypy.rpython.rarithmetic import r_uint, r_ulonglong, r_longlong
from pypy.rpython.objectmodel import Symbolic
from pypy.tool.uid import Hashable
from pypy.tool.tls import tlsobject
+from pypy.tool.picklesupport import getstate_with_slots, setstate_with_slots, pickleable_weakref
from types import NoneType
from sys import maxint
@@ -118,6 +118,9 @@
def _is_varsize(self):
return False
+ __getstate__ = getstate_with_slots
+ __setstate__ = setstate_with_slots
+
NFOUND = object()
class ContainerType(LowLevelType):
@@ -647,7 +650,7 @@
obj0 = pointing_to
else:
self._set_weak(True)
- obj0 = weakref.ref(pointing_to)
+ obj0 = pickleable_weakref(pointing_to)
self._set_solid(solid)
self._set_obj0(obj0)
@@ -751,6 +754,9 @@
return callb(*args)
raise TypeError("%r instance is not a function" % (self._T,))
+ __getstate__ = getstate_with_slots
+ __setstate__ = setstate_with_slots
+
assert not '__dict__' in dir(_ptr)
class _parentable(object):
@@ -766,7 +772,7 @@
self._TYPE = TYPE
def _setparentstructure(self, parent, parentindex):
- self._wrparent = weakref.ref(parent)
+ self._wrparent = pickleable_weakref(parent)
self._parent_type = typeOf(parent)
self._parent_index = parentindex
if (isinstance(self._parent_type, Struct)
@@ -789,6 +795,8 @@
def _check(self):
self._parentstructure()
+ __getstate__ = getstate_with_slots
+ __setstate__ = setstate_with_slots
def _struct_variety(flds, cache={}):
flds = list(flds)
@@ -801,7 +809,12 @@
__slots__ = flds
cache[tag] = _struct1
return _struct1
-
+
+#for pickling support:
+def _get_empty_instance_of_struct_variety(flds):
+ cls = _struct_variety(flds)
+ return object.__new__(cls)
+
class _struct(_parentable):
_kind = "structure"
@@ -843,6 +856,11 @@
def __str__(self):
return 'struct %s { %s }' % (self._TYPE._name, self._str_fields())
+ def __reduce__(self):
+ return _get_empty_instance_of_struct_variety, (self.__slots__, ), getstate_with_slots(self)
+
+ __setstate__ = setstate_with_slots
+
class _array(_parentable):
_kind = "array"
Added: pypy/dist/pypy/rpython/lltypesystem/test/test_picklelltype.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_picklelltype.py Tue Jan 31 15:38:29 2006
@@ -0,0 +1,408 @@
+from pypy.rpython.lltypesystem.lltype import *
+
+import pickle
+
+def isweak(p, T):
+ return p._weak and typeOf(p).TO == T
+
+def test_pickle_types():
+ S0 = GcStruct("s0", ('a', Signed), ('b', Signed))
+ p_S0 = pickle.dumps(S0)
+ r_S0 = pickle.loads(p_S0)
+ assert S0 == r_S0
+ assert hash(S0) == hash(r_S0)
+ s0 = malloc(S0)
+ print s0
+ s0.a = 1
+ s0.b = s0.a
+ p_s0 = pickle.dumps(s0)
+ r_s0 = pickle.loads(p_s0)
+ # simple array
+ Ar = GcArray(('v', Signed))
+ p_Ar = pickle.dumps(Ar)
+ r_Ar = pickle.loads(p_Ar)
+ assert Ar == r_Ar
+ x = malloc(Ar,0)
+ p_x = pickle.dumps(x)
+ r_x = pickle.loads(p_x)
+ assert len(r_x) == 0
+ x = malloc(Ar,3)
+ x[0].v = 1
+ x[1].v = 2
+ x[2].v = 3
+ p_x = pickle.dumps(x)
+ r_x = pickle.loads(p_x)
+ assert typeOf(x) == Ptr(Ar)
+ assert isweak(x[0], Ar.OF)
+ assert typeOf(x[0].v) == Signed
+ assert [x[z].v for z in range(3)] == [1, 2, 3]
+ #
+ def define_list(T):
+ List_typ = GcStruct("list",
+ ("items", Ptr(GcArray(('item',T)))))
+ def newlist():
+ l = malloc(List_typ)
+ items = malloc(List_typ.items.TO, 0)
+ l.items = items
+ return l
+
+ def append(l, newitem):
+ length = len(l.items)
+ newitems = malloc(List_typ.items.TO, length+1)
+ i = 0
+ while i<length:
+ newitems[i].item = l.items[i].item
+ i += 1
+ newitems[length].item = newitem
+ l.items = newitems
+
+ def item(l, i):
+ return l.items[i].item
+
+ return List_typ, newlist, append, item
+
+ List_typ, inewlist, iappend, iitem = define_list(Signed)
+
+ l = inewlist()
+ iappend(l, 2)
+ iappend(l, 3)
+ p_l = pickle.dumps(l)
+ r_l = pickle.loads(p_l)
+ assert len(r_l.items) == 2
+ assert iitem(r_l, 0) == 2
+ assert iitem(r_l, 1) == 3
+
+ IWrap = GcStruct("iwrap", ('v', Signed))
+ List_typ, iwnewlist, iwappend, iwitem = define_list(Ptr(IWrap))
+
+ l = iwnewlist()
+ iw2 = malloc(IWrap)
+ iw3 = malloc(IWrap)
+ iw2.v = 2
+ iw3.v = 3
+ iwappend(l, iw2)
+ iwappend(l, iw3)
+ p_l = pickle.dumps(l)
+ r_l = pickle.loads(p_l)
+ assert len(r_l.items) == 2
+ assert iwitem(r_l, 0).v == 2
+ assert iwitem(r_l, 1).v == 3
+
+def test_varsizestruct():
+ S1 = GcStruct("s1", ('a', Signed), ('rest', Array(('v', Signed))))
+ py.test.raises(TypeError, "malloc(S1)")
+ s1 = malloc(S1, 4)
+ p_s1 = pickle.dumps(s1)
+ r_s1 = pickle.loads(p_s1)
+ assert r_s1.a == 0
+ assert isweak(r_s1.rest, S1.rest)
+ assert len(r_s1.rest) == 4
+ assert isweak(r_s1.rest[0], S1.rest.OF)
+ assert typeOf(r_s1.rest[0].v) == Signed
+ assert r_s1.rest[0].v == 0
+ py.test.raises(IndexError, "r_s1.rest[4]")
+ py.test.raises(IndexError, "r_s1.rest[-1]")
+
+ s1.a = 17
+ s1.rest[3].v = 5
+ p_s1 = pickle.dumps(s1)
+ r_s1 = pickle.loads(p_s1)
+ assert r_s1.a == 17
+ assert r_s1.rest[3].v == 5
+
+def test_substructure_ptr():
+ S3 = Struct("s3", ('a', Signed))
+ S2 = Struct("s2", ('s3', S3))
+ S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2))
+ p1 = malloc(S1)
+ p_p1 = pickle.dumps(p1)
+ r_p1 = pickle.loads(p_p1)
+ assert isweak(r_p1.sub1, S2)
+ assert isweak(r_p1.sub2, S2)
+ assert isweak(r_p1.sub1.s3, S3)
+ r_p2 = r_p1.sub1
+ assert isweak(r_p2.s3, S3)
+
+def test_gc_substructure_ptr():
+ S1 = GcStruct("s2", ('a', Signed))
+ S2 = Struct("s3", ('a', Signed))
+ S0 = GcStruct("s1", ('sub1', S1), ('sub2', S2))
+ p1 = malloc(S0)
+ r_p1 = pickle.loads(pickle.dumps(p1))
+ assert typeOf(r_p1.sub1) == Ptr(S1)
+ assert isweak(r_p1.sub2, S2)
+
+def test_cast_simple_widening():
+ S2 = Struct("s2", ('a', Signed))
+ S1 = Struct("s1", ('sub1', S2), ('sub2', S2))
+ p1 = malloc(S1, immortal=True)
+ r_p1 = pickle.loads(pickle.dumps(p1))
+ p2 = r_p1.sub1
+ p3 = p2
+ assert typeOf(p3) == Ptr(S2)
+ p4 = cast_pointer(Ptr(S1), p3)
+ assert typeOf(p4) == Ptr(S1)
+ assert p4 == r_p1
+
+def test_best_effort_gced_parent_detection():
+ S2 = Struct("s2", ('a', Signed))
+ S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2), ('tail', Array(('e', Signed))))
+ p1 = malloc(S1, 1)
+ p2 = p1.sub2
+ p3 = p1.tail
+ p3[0].e = 1
+ r_p2 = pickle.loads(pickle.dumps(p2))
+ py.test.raises(RuntimeError, "r_p2.a")
+ r_p1 = pickle.loads(pickle.dumps(p1))
+ r_p2 = r_p1.sub2
+ r_p3 = r_p1.tail
+ assert r_p3[0].e == 1
+ del r_p1
+ import gc
+ gc.collect()
+ py.test.raises(RuntimeError, "r_p2.a")
+ py.test.raises(RuntimeError, "r_p3[0]")
+
+def test_best_effort_gced_parent_for_arrays():
+ A1 = GcArray(('v', Signed))
+ p1 = malloc(A1, 10)
+ p1[5].v = 3
+ p1_5 = p1[5]
+ r_p1_5 = pickle.loads(pickle.dumps(p1_5))
+ py.test.raises(RuntimeError, "r_p1_5.v")
+ r_p1 = pickle.loads(pickle.dumps(p1))
+ r_p1_5 = r_p1[5]
+ assert r_p1[0].v == 0
+ assert r_p1[9].v == 0
+ assert r_p1[5].v == 3
+ del r_p1
+ import gc
+ gc.collect()
+ py.test.raises(RuntimeError, "r_p1_5.v")
+
+def DONOTtest_functions():
+ F = FuncType((Signed,), Signed)
+ py.test.raises(TypeError, "Struct('x', ('x', F))")
+
+ PF = Ptr(F)
+ pf = PF._example()
+ assert pf(0) == 0
+ py.test.raises(TypeError, pf, 0, 0)
+ py.test.raises(TypeError, pf, 'a')
+
+def test_forward_reference():
+ F = GcForwardReference()
+ S = GcStruct('abc', ('x', Ptr(F)))
+ F.become(S)
+ assert S.x == Ptr(S)
+ py.test.raises(TypeError, "GcForwardReference().become(Struct('abc'))")
+ ForwardReference().become(Struct('abc'))
+ r_S = pickle.loads(pickle.dumps(S))
+ assert hash(S) == hash(r_S)
+
+def DONOTtest_nullptr():
+ S = Struct('s')
+ p0 = nullptr(S)
+ assert not p0
+ assert typeOf(p0) == Ptr(S)
+
+def DONOTtest_nullptr_cast():
+ S = Struct('s')
+ p0 = nullptr(S)
+ assert not p0
+ S1 = Struct("s1", ('s', S))
+ p10 = cast_pointer(Ptr(S1), p0)
+ assert typeOf(p10) == Ptr(S1)
+ assert not p10
+
+
+def DONOTtest_hash():
+ S = ForwardReference()
+ S.become(Struct('S', ('p', Ptr(S))))
+ assert S == S
+ hash(S) # assert no crash, and force the __cached_hash computation
+ S1 = Struct('S', ('p', Ptr(S)))
+ assert S1 == S
+ assert S == S1
+ assert hash(S1) == hash(S)
+
+def DONOTtest_array_with_non_container_elements():
+ As = GcArray(Signed)
+ a = malloc(As, 3)
+ assert typeOf(a) == Ptr(As)
+ assert a[0] == 0
+ assert a[1] == 0
+ assert a[2] == 0
+ a[1] = 3
+ assert a[1] == 3
+ S = GcStruct('s', ('x', Signed))
+ s = malloc(S)
+ py.test.raises(TypeError, "a[1] = s")
+ S = GcStruct('s', ('x', Signed))
+ py.test.raises(TypeError, "Array(S)")
+ py.test.raises(TypeError, "Array(As)")
+ S = Struct('s', ('x', Signed))
+ A = GcArray(S)
+ a = malloc(A, 2)
+ s = S._container_example() # should not happen anyway
+ py.test.raises(TypeError, "a[0] = s")
+ S = Struct('s', ('last', Array(S)))
+ py.test.raises(TypeError, "Array(S)")
+
+def DONOTtest_immortal_parent():
+ S1 = GcStruct('substruct', ('x', Signed))
+ S = GcStruct('parentstruct', ('s1', S1))
+ p = malloc(S, immortal=True)
+ p1 = p.s1
+ p1.x = 5
+ del p
+ p = cast_pointer(Ptr(S), p1)
+ assert p.s1.x == 5
+
+def DONOTtest_getRuntimeTypeInfo():
+ S = GcStruct('s', ('x', Signed))
+ py.test.raises(ValueError, "getRuntimeTypeInfo(S)")
+ pinf0 = attachRuntimeTypeInfo(S)
+ assert pinf0._obj.about == S
+ pinf = getRuntimeTypeInfo(S)
+ assert pinf == pinf0
+ pinf1 = getRuntimeTypeInfo(S)
+ assert pinf == pinf1
+ Z = GcStruct('z', ('x', Unsigned))
+ attachRuntimeTypeInfo(Z)
+ assert getRuntimeTypeInfo(Z) != pinf0
+ Sbis = GcStruct('s', ('x', Signed))
+ attachRuntimeTypeInfo(Sbis)
+ assert getRuntimeTypeInfo(Sbis) != pinf0
+ assert Sbis != S # the attached runtime type info distinguishes them
+
+def DONOTtest_getRuntimeTypeInfo_destrpointer():
+ S = GcStruct('s', ('x', Signed))
+ def f(s):
+ s.x = 1
+ def type_info_S(p):
+ return getRuntimeTypeInfo(S)
+ qp = functionptr(FuncType([Ptr(S)], Ptr(RuntimeTypeInfo)),
+ "type_info_S",
+ _callable=type_info_S)
+ dp = functionptr(FuncType([Ptr(S)], Void),
+ "destructor_funcptr",
+ _callable=f)
+ pinf0 = attachRuntimeTypeInfo(S, qp, destrptr=dp)
+ assert pinf0._obj.about == S
+ pinf = getRuntimeTypeInfo(S)
+ assert pinf == pinf0
+ pinf1 = getRuntimeTypeInfo(S)
+ assert pinf == pinf1
+ assert pinf._obj.destructor_funcptr == dp
+ assert pinf._obj.query_funcptr == qp
+
+def DONOTtest_runtime_type_info():
+ S = GcStruct('s', ('x', Signed))
+ attachRuntimeTypeInfo(S)
+ s = malloc(S)
+ assert runtime_type_info(s) == getRuntimeTypeInfo(S)
+ S1 = GcStruct('s1', ('sub', S), ('x', Signed))
+ attachRuntimeTypeInfo(S1)
+ s1 = malloc(S1)
+ assert runtime_type_info(s1) == getRuntimeTypeInfo(S1)
+ assert runtime_type_info(s1.sub) == getRuntimeTypeInfo(S1)
+ assert runtime_type_info(cast_pointer(Ptr(S), s1)) == getRuntimeTypeInfo(S1)
+ def dynamic_type_info_S(p):
+ if p.x == 0:
+ return getRuntimeTypeInfo(S)
+ else:
+ return getRuntimeTypeInfo(S1)
+ fp = functionptr(FuncType([Ptr(S)], Ptr(RuntimeTypeInfo)),
+ "dynamic_type_info_S",
+ _callable=dynamic_type_info_S)
+ attachRuntimeTypeInfo(S, fp)
+ assert s.x == 0
+ assert runtime_type_info(s) == getRuntimeTypeInfo(S)
+ s.x = 1
+ py.test.raises(RuntimeError, "runtime_type_info(s)")
+ assert s1.sub.x == 0
+ py.test.raises(RuntimeError, "runtime_type_info(s1.sub)")
+ s1.sub.x = 1
+ assert runtime_type_info(s1.sub) == getRuntimeTypeInfo(S1)
+
+def DONOTtest_flavor_malloc():
+ S = Struct('s', ('x', Signed))
+ py.test.raises(TypeError, malloc, S)
+ p = malloc(S, flavor="raw")
+ assert typeOf(p).TO == S
+ assert not isweak(p, S)
+
+def DONOTtest_opaque():
+ O = OpaqueType('O')
+ p1 = opaqueptr(O, 'p1', hello="world")
+ assert typeOf(p1) == Ptr(O)
+ assert p1._obj.hello == "world"
+ assert parentlink(p1._obj) == (None, None)
+ S = GcStruct('S', ('stuff', O))
+ p2 = malloc(S)
+ assert typeOf(p2) == Ptr(S)
+ assert typeOf(p2.stuff) == Ptr(O)
+ assert parentlink(p2.stuff._obj) == (p2._obj, 'stuff')
+
+def DONOTtest_is_atomic():
+ U = Struct('inlined', ('z', Signed))
+ A = Ptr(RuntimeTypeInfo)
+ P = Ptr(GcStruct('p'))
+ Q = GcStruct('q', ('i', Signed), ('u', U), ('p', P))
+ O = OpaqueType('O')
+ F = GcForwardReference()
+ assert A._is_atomic() is True
+ assert P._is_atomic() is False
+ assert Q.i._is_atomic() is True
+ assert Q.u._is_atomic() is True
+ assert Q.p._is_atomic() is False
+ assert Q._is_atomic() is False
+ assert O._is_atomic() is False
+ assert F._is_atomic() is False
+
+def DONOTtest_adtmeths():
+ def h_newstruct():
+ return malloc(S)
+
+ S = GcStruct('s', ('x', Signed),
+ adtmeths={"h_newstruct": h_newstruct})
+
+ s = S.h_newstruct()
+
+ assert typeOf(s) == Ptr(S)
+
+ def h_alloc(n):
+ return malloc(A, n)
+
+ def h_length(a):
+ return len(a)
+
+ A = GcArray(Signed,
+ adtmeths={"h_alloc": h_alloc,
+ "h_length": h_length})
+
+ a = A.h_alloc(10)
+
+ assert typeOf(a) == Ptr(A)
+ assert len(a) == 10
+
+ assert a.h_length() == 10
+
+def DONOTtest_adt_typemethod():
+ def h_newstruct(S):
+ return malloc(S)
+ h_newstruct = typeMethod(h_newstruct)
+
+ S = GcStruct('s', ('x', Signed),
+ adtmeths={"h_newstruct": h_newstruct})
+
+ s = S.h_newstruct()
+
+ assert typeOf(s) == Ptr(S)
+
+ Sprime = GcStruct('s', ('x', Signed),
+ adtmeths={"h_newstruct": h_newstruct})
+
+ assert S == Sprime
+
More information about the Pypy-commit
mailing list