cython

Форк
0
/
pep442_tp_finalize.pyx 
381 строка · 6.6 Кб
1
# mode: run
2

3
from __future__ import print_function
4

5
cimport cython
6

7
import gc
8

9
cdef class nontrivial_del:
10
    def __init__(self):
11
        print("init")
12

13
    def __del__(self):
14
        print("del")
15

16
def test_del():
17
    """
18
    >>> test_del()
19
    start
20
    init
21
    del
22
    finish
23
    """
24
    print("start")
25
    d = nontrivial_del()
26
    d = None
27
    gc.collect()
28
    print("finish")
29

30

31
cdef class del_and_dealloc:
32
    def __init__(self):
33
        print("init")
34

35
    def __del__(self):
36
        print("del")
37

38
    def __dealloc__(self):
39
        print("dealloc")
40

41
def test_del_and_dealloc():
42
    """
43
    >>> test_del_and_dealloc()
44
    start
45
    init
46
    del
47
    dealloc
48
    finish
49
    """
50
    print("start")
51
    d = del_and_dealloc()
52
    d = None
53
    gc.collect()
54
    print("finish")
55

56
@cython.final
57
cdef class FinalClass:
58
    def __init__(self):
59
        print("init")
60
    def __del__(self):
61
        print("del")
62

63
def test_final_class():
64
    """
65
    >>> test_final_class()
66
    start
67
    init
68
    del
69
    finish
70
    """
71
    print("start")
72
    d = FinalClass()
73
    d = None
74
    gc.collect()
75
    print("finish")
76

77
@cython.final
78
cdef class FinalInherits(nontrivial_del):
79
    def __init__(self):
80
        super().__init__()
81
        print("FinalInherits init")
82
    # no __del__ but nontrivial_del should still be called
83
    def __dealloc__(self):
84
        pass  # define __dealloc__ so as not to fall back on base __dealloc__
85

86
def test_final_inherited():
87
    """
88
    >>> test_final_inherited()
89
    start
90
    init
91
    FinalInherits init
92
    del
93
    finish
94
    """
95
    print("start")
96
    d = FinalInherits()
97
    d = None
98
    gc.collect()
99
    print("finish")
100

101
cdef class DummyBase:
102
    pass
103

104
class RegularClass:
105
    __slots__ = ()
106
    def __del__(self):
107
        print("del")
108

109
@cython.final
110
cdef class FinalMultipleInheritance(DummyBase, RegularClass):
111
    def __init__(self):
112
        super().__init__()
113
        print("init")
114
    def __dealloc__(self):
115
        pass
116

117
def test_final_multiple_inheritance():
118
    """
119
    >>> test_final_multiple_inheritance()
120
    start
121
    init
122
    del
123
    finish
124
    """
125
    print("start")
126
    d = FinalMultipleInheritance()
127
    d = None
128
    gc.collect()
129
    print("finish")
130

131
cdef class del_with_exception:
132
    def __init__(self):
133
        print("init")
134

135
    def __del__(self):
136
        print("del")
137
        raise Exception("Error")
138

139
def test_del_with_exception():
140
    """
141
    >>> test_del_with_exception()
142
    start
143
    init
144
    del
145
    finish
146
    """
147
    print("start")
148
    d = nontrivial_del()
149
    d = None
150
    gc.collect()
151
    print("finish")
152

153

154
def test_nontrivial_del_with_exception():
155
    """
156
    >>> test_nontrivial_del_with_exception()
157
    start
158
    init
159
    del
160
    end
161
    """
162
    print("start")
163
    def inner():
164
        c = nontrivial_del()
165
        raise RuntimeError()
166

167
    try:
168
        inner()
169
    except RuntimeError:
170
        pass
171

172
    print("end")
173

174

175
cdef class parent:
176
    def __del__(self):
177
        print("del parent")
178

179
class child(parent):
180
    def __del__(self):
181
        print("del child")
182

183
def test_del_inheritance():
184
    """
185
    >>> test_del_inheritance()
186
    start
187
    del child
188
    finish
189
    """
190
    print("start")
191
    c = child()
192
    c = None
193
    gc.collect()
194
    print("finish")
195

196

197
cdef class cy_parent:
198
    def __del__(self):
199
        print("del cy_parent")
200

201
    def __dealloc__(self):
202
        print("dealloc cy_parent")
203

204
class py_parent:
205
    def __del__(self):
206
        print("del py_parent")
207

208
class multi_child(cy_parent, py_parent):
209
    def __del__(self):
210
        print("del child")
211

212
def test_multiple_inheritance():
213
    """
214
    >>> test_multiple_inheritance()
215
    start
216
    del child
217
    dealloc cy_parent
218
    finish
219
    """
220
    print("start")
221
    c = multi_child()
222
    c = None
223
    gc.collect()
224
    print("finish")
225

226

227
cdef class zombie_object:
228
    def __del__(self):
229
        global global_zombie_object
230
        print("del")
231
        global_zombie_object = self
232

233
    def __dealloc__(self):
234
        print("dealloc")
235

236
def test_zombie_object():
237
    """
238
    >>> test_zombie_object()
239
    start
240
    del
241
    del global
242
    del
243
    finish
244
    """
245
    global global_zombie_object
246
    print("start")
247
    i = zombie_object()
248
    i = None
249
    print("del global")
250
    del global_zombie_object
251
    gc.collect()
252
    print("finish")
253

254

255
# Same as above, but the member
256
# makes the class GC, so it
257
# is deallocated
258
cdef class gc_zombie_object:
259
    cdef object x
260

261
    def __del__(self):
262
        global global_gc_zombie_object
263
        print("del")
264
        global_gc_zombie_object = self
265

266
    def __dealloc__(self):
267
        print("dealloc")
268

269
def test_gc_zombie_object():
270
    """
271
    >>> test_gc_zombie_object()
272
    start
273
    del
274
    del global
275
    dealloc
276
    finish
277
    """
278
    global global_gc_zombie_object
279
    print("start")
280
    i = gc_zombie_object()
281
    i = None
282
    print("del global")
283
    del global_gc_zombie_object
284
    gc.collect()
285
    print("finish")
286

287

288
cdef class cdef_parent:
289
    pass
290

291
cdef class cdef_child(cdef_parent):
292
    def __del__(self):
293
        print("del")
294
    def __dealloc__(self):
295
        print("dealloc")
296

297
def test_cdef_parent_object():
298
    """
299
    >>> test_cdef_parent_object()
300
    start
301
    del
302
    dealloc
303
    finish
304
    """
305
    print("start")
306
    i = cdef_child()
307
    i = None
308
    gc.collect()
309
    print("finish")
310

311

312
cdef class cdef_nontrivial_parent:
313
    def __del__(self):
314
        print("del parent")
315
    def __dealloc__(self):
316
        print("dealloc parent")
317

318
cdef class cdef_nontrivial_child(cdef_nontrivial_parent):
319
    def __del__(self):
320
        print("del child")
321
    def __dealloc__(self):
322
        print("dealloc child")
323

324
def test_cdef_nontrivial_parent_object():
325
    """
326
    >>> test_cdef_nontrivial_parent_object()
327
    start
328
    del child
329
    dealloc child
330
    dealloc parent
331
    finish
332
    """
333
    print("start")
334
    i = cdef_nontrivial_child()
335
    i = None
336
    gc.collect()
337
    print("finish")
338

339

340
class python_child(cdef_nontrivial_parent):
341
    def __del__(self):
342
        print("del python child")
343
        super().__del__()
344

345
def test_python_child_object():
346
    """
347
    >>> test_python_child_object()
348
    Traceback (most recent call last):
349
    ...
350
    RuntimeError: End function
351
    """
352

353
    def func(tp):
354
        inst = tp()
355
        raise RuntimeError("End function")
356

357
    func(python_child)
358

359
def test_python_child_fancy_inherit():
360
    """
361
    >>> test_python_child_fancy_inherit()
362
    Traceback (most recent call last):
363
    ...
364
    RuntimeError: End function
365
    """
366

367
    # inherit using "true python" rather than Cython
368
    globs = { 'cdef_nontrivial_parent': cdef_nontrivial_parent }
369

370
    exec("""
371
class derived_python_child(cdef_nontrivial_parent):
372
    pass
373
""", globs)
374

375
    derived_python_child = globs['derived_python_child']
376

377
    def func(tp):
378
        inst = tp()
379
        raise RuntimeError("End function")
380

381
    func(derived_python_child)
382

383

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.