1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
import py, weakref
from rpython.rlib import rgc
from rpython.rtyper.lltypesystem import lltype, llmemory
from rpython.rtyper.test.tool import BaseRtypingTest
class TestRweakref(BaseRtypingTest):
def test_weakref_simple(self):
class A:
pass
class B(A):
pass
class C(A):
pass
def f(n):
if n:
x = B()
x.hello = 42
r = weakref.ref(x)
else:
x = C()
x.hello = 64
r = weakref.ref(x)
return r().hello, x # returns 'x' too, to keep it alive
res = self.interpret(f, [1])
assert res.item0 == 42
res = self.interpret(f, [0])
assert res.item0 == 64
def test_prebuilt_weakref(self):
class A:
pass
a1 = A()
a1.hello = 5
w1 = weakref.ref(a1)
a2 = A()
a2.hello = 8
w2 = weakref.ref(a2)
def f(n):
if n:
r = w1
else:
r = w2
return r().hello
res = self.interpret(f, [1])
assert res == 5
res = self.interpret(f, [0])
assert res == 8
def test_prebuilt_dead_weakref(self):
class A:
pass
a1 = A()
w1 = weakref.ref(a1)
a2 = A()
w2 = weakref.ref(a2)
del a1
rgc.collect()
assert w1() is None
def f(n):
if n:
r = w1
else:
r = w2
return r() is not None
res = self.interpret(f, [1])
assert res == False
res = self.interpret(f, [0])
assert res == True
def test_multiple_prebuilt_dead_weakrefs(self):
class A:
pass
a1 = A()
w1 = weakref.ref(a1)
a2 = A()
w2 = weakref.ref(a2)
a3 = A()
w3 = weakref.ref(a3)
a4 = A()
w4 = weakref.ref(a4)
del a1, a3
rgc.collect()
assert w1() is None
assert w3() is None
def f(n):
if n > 0:
if n > 5:
r = w1
else:
r = w3
assert r() is None
else:
if n < -5:
r = w2
else:
r = w4
assert r() is not None
return r() is not None
res = self.interpret(f, [1])
assert res == False
res = self.interpret(f, [0])
assert res == True
res = self.interpret(f, [100])
assert res == False
res = self.interpret(f, [-100])
assert res == True
def test_pbc_null_weakref(self):
class A:
pass
a1 = A()
mylist = [weakref.ref(a1), None]
def fn(i):
item = mylist[i]
return item is None
assert self.interpret(fn, [0]) is False
assert self.interpret(fn, [1]) is True
def test_ll_weakref(self):
S = lltype.GcStruct('S', ('x',lltype.Signed))
def g():
s = lltype.malloc(S)
w = llmemory.weakref_create(s)
assert llmemory.weakref_deref(lltype.Ptr(S), w) == s
assert llmemory.weakref_deref(lltype.Ptr(S), w) == s
return w # 's' is forgotten here
def f():
w = g()
rgc.collect()
return llmemory.weakref_deref(lltype.Ptr(S), w)
res = self.interpret(f, [])
assert res == lltype.nullptr(S)
class TestRWeakrefDisabled(BaseRtypingTest):
def test_no_real_weakref(self):
class A:
pass
a1 = A()
mylist = [weakref.ref(a1), None]
def g():
a2 = A()
return weakref.ref(a2)
def fn(i):
w = g()
rgc.collect()
assert w() is not None
return mylist[i] is None
assert self.interpret(fn, [0], rweakref=False) is False
assert self.interpret(fn, [1], rweakref=False) is True
|