File: test_del.py

package info (click to toggle)
pypy 5.6.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 97,040 kB
  • ctags: 185,069
  • sloc: python: 1,147,862; ansic: 49,642; cpp: 5,245; asm: 5,169; makefile: 529; sh: 481; xml: 232; lisp: 45
file content (127 lines) | stat: -rw-r--r-- 3,916 bytes parent folder | download
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
import py
from rpython.rlib.jit import JitDriver, dont_look_inside
from rpython.rlib.objectmodel import keepalive_until_here
from rpython.rlib import rgc
from rpython.jit.metainterp.test.support import LLJitMixin


class DelTests:

    def test_del_keep_obj(self):
        myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
        class Foo:
            def __del__(self):
                pass
        def f(n):
            x = None
            while n > 0:
                myjitdriver.can_enter_jit(x=x, n=n)
                myjitdriver.jit_merge_point(x=x, n=n)
                x = Foo()
                Foo()
                n -= 1
            return 42
        self.meta_interp(f, [20])
        self.check_resops({'call_r': 4,      # calls to a helper function
                           'guard_no_exception': 4,    # follows the calls
                           'int_sub': 2,
                           'int_gt': 2,
                           'guard_true': 2,
                           'jump': 1})

    def test_class_of_allocated(self):
        myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
        class Foo:
            def __del__(self):
                pass
            def f(self):
                return self.meth()
        class X(Foo):
            def meth(self):
                return 456
        class Y(Foo):
            def meth(self):
                return 123
        def f(n):
            x = None
            while n > 0:
                myjitdriver.can_enter_jit(x=x, n=n)
                myjitdriver.jit_merge_point(x=x, n=n)
                x = X()
                y = Y()
                assert x.f() == 456
                assert y.f() == 123
                n -= 1
            return 42
        res = self.meta_interp(f, [20])
        assert res == 42

    def test_instantiate_with_or_without_del(self):
        import gc
        mydriver = JitDriver(reds = ['n', 'x'], greens = [])
        class Base: pass
        class A(Base): foo = 72
        class B(Base):
            foo = 8
            def __del__(self):
                pass
        def f(n):
            x = 0
            while n > 0:
                mydriver.can_enter_jit(n=n, x=x)
                mydriver.jit_merge_point(n=n, x=x)
                if n % 2 == 0:
                    cls = A
                else:
                    cls = B
                inst = cls()
                x += inst.foo
                n -= 1
            return 1
        res = self.meta_interp(f, [20], enable_opts='')
        assert res == 1
        self.check_resops(call_r=1)   # for the case B(), but not for the case A()

    def test_keepalive(self):
        py.test.skip("XXX fails")   # hum, I think the test itself is broken
        #
        mydriver = JitDriver(reds = ['n', 'states'], greens = [])
        class State:
            num = 1
        class X:
            def __init__(self, state):
                self.state = state
            def __del__(self):
                self.state.num += 1
        @dont_look_inside
        def do_stuff():
            pass
        def f(n):
            states = []
            while n > 0:
                mydriver.jit_merge_point(n=n, states=states)
                state = State()
                states.append(state)
                x = X(state)
                do_stuff()
                state.num *= 1000
                do_stuff()
                keepalive_until_here(x)
                n -= 1
            return states
        def main(n):
            states = f(n)
            rgc.collect()
            rgc.collect()
            err = 1001
            for state in states:
                if state.num != 1001:
                    err = state.num
                    print 'ERROR:', err
            return err
        assert main(20) == 1001
        res = self.meta_interp(main, [20])
        assert res == 1001

class TestLLtype(DelTests, LLJitMixin):
    pass