μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
test_call_policies.py
Go to the documentation of this file.
1import pytest
2
3import env # noqa: F401
4from pybind11_tests import ConstructorStats
5from pybind11_tests import call_policies as m
6
7
8@pytest.mark.xfail("env.PYPY", reason="sometimes comes out 1 off on PyPy", strict=False)
9def test_keep_alive_argument(capture):
10 n_inst = ConstructorStats.detail_reg_inst()
11 with capture:
12 p = m.Parent()
13 assert capture == "Allocating parent."
14 with capture:
15 p.addChild(m.Child())
16 assert ConstructorStats.detail_reg_inst() == n_inst + 1
17 assert (
18 capture
19 == """
20 Allocating child.
21 Releasing child.
22 """
23 )
24 with capture:
25 del p
26 assert ConstructorStats.detail_reg_inst() == n_inst
27 assert capture == "Releasing parent."
28
29 with capture:
30 p = m.Parent()
31 assert capture == "Allocating parent."
32 with capture:
33 p.addChildKeepAlive(m.Child())
34 assert ConstructorStats.detail_reg_inst() == n_inst + 2
35 assert capture == "Allocating child."
36 with capture:
37 del p
38 assert ConstructorStats.detail_reg_inst() == n_inst
39 assert (
40 capture
41 == """
42 Releasing parent.
43 Releasing child.
44 """
45 )
46
47 p = m.Parent()
48 c = m.Child()
49 assert ConstructorStats.detail_reg_inst() == n_inst + 2
50 m.free_function(p, c)
51 del c
52 assert ConstructorStats.detail_reg_inst() == n_inst + 2
53 del p
54 assert ConstructorStats.detail_reg_inst() == n_inst
55
56 with pytest.raises(RuntimeError) as excinfo:
57 m.invalid_arg_index()
58 assert str(excinfo.value) == "Could not activate keep_alive!"
59
60
61def test_keep_alive_return_value(capture):
62 n_inst = ConstructorStats.detail_reg_inst()
63 with capture:
64 p = m.Parent()
65 assert capture == "Allocating parent."
66 with capture:
67 p.returnChild()
68 assert ConstructorStats.detail_reg_inst() == n_inst + 1
69 assert (
70 capture
71 == """
72 Allocating child.
73 Releasing child.
74 """
75 )
76 with capture:
77 del p
78 assert ConstructorStats.detail_reg_inst() == n_inst
79 assert capture == "Releasing parent."
80
81 with capture:
82 p = m.Parent()
83 assert capture == "Allocating parent."
84 with capture:
85 p.returnChildKeepAlive()
86 assert ConstructorStats.detail_reg_inst() == n_inst + 2
87 assert capture == "Allocating child."
88 with capture:
89 del p
90 assert ConstructorStats.detail_reg_inst() == n_inst
91 assert (
92 capture
93 == """
94 Releasing parent.
95 Releasing child.
96 """
97 )
98
99 p = m.Parent()
100 assert ConstructorStats.detail_reg_inst() == n_inst + 1
101 with capture:
102 m.Parent.staticFunction(p)
103 assert ConstructorStats.detail_reg_inst() == n_inst + 2
104 assert capture == "Allocating child."
105 with capture:
106 del p
107 assert ConstructorStats.detail_reg_inst() == n_inst
108 assert (
109 capture
110 == """
111 Releasing parent.
112 Releasing child.
113 """
114 )
115
116
117# https://foss.heptapod.net/pypy/pypy/-/issues/2447
118@pytest.mark.xfail("env.PYPY", reason="_PyObject_GetDictPtr is unimplemented")
119def test_alive_gc(capture):
120 n_inst = ConstructorStats.detail_reg_inst()
121 p = m.ParentGC()
122 p.addChildKeepAlive(m.Child())
123 assert ConstructorStats.detail_reg_inst() == n_inst + 2
124 lst = [p]
125 lst.append(lst) # creates a circular reference
126 with capture:
127 del p, lst
128 assert ConstructorStats.detail_reg_inst() == n_inst
129 assert (
130 capture
131 == """
132 Releasing parent.
133 Releasing child.
134 """
135 )
136
137
138def test_alive_gc_derived(capture):
139 class Derived(m.Parent):
140 pass
141
142 n_inst = ConstructorStats.detail_reg_inst()
143 p = Derived()
144 p.addChildKeepAlive(m.Child())
145 assert ConstructorStats.detail_reg_inst() == n_inst + 2
146 lst = [p]
147 lst.append(lst) # creates a circular reference
148 with capture:
149 del p, lst
150 assert ConstructorStats.detail_reg_inst() == n_inst
151 assert (
152 capture
153 == """
154 Releasing parent.
155 Releasing child.
156 """
157 )
158
159
160def test_alive_gc_multi_derived(capture):
161 class Derived(m.Parent, m.Child):
162 def __init__(self):
163 m.Parent.__init__(self)
164 m.Child.__init__(self)
165
166 n_inst = ConstructorStats.detail_reg_inst()
167 p = Derived()
168 p.addChildKeepAlive(m.Child())
169 # +3 rather than +2 because Derived corresponds to two registered instances
170 assert ConstructorStats.detail_reg_inst() == n_inst + 3
171 lst = [p]
172 lst.append(lst) # creates a circular reference
173 with capture:
174 del p, lst
175 assert ConstructorStats.detail_reg_inst() == n_inst
176 assert (
177 capture
178 == """
179 Releasing parent.
180 Releasing child.
181 Releasing child.
182 """
183 )
184
185
186def test_return_none(capture):
187 n_inst = ConstructorStats.detail_reg_inst()
188 with capture:
189 p = m.Parent()
190 assert capture == "Allocating parent."
191 with capture:
192 p.returnNullChildKeepAliveChild()
193 assert ConstructorStats.detail_reg_inst() == n_inst + 1
194 assert capture == ""
195 with capture:
196 del p
197 assert ConstructorStats.detail_reg_inst() == n_inst
198 assert capture == "Releasing parent."
199
200 with capture:
201 p = m.Parent()
202 assert capture == "Allocating parent."
203 with capture:
204 p.returnNullChildKeepAliveParent()
205 assert ConstructorStats.detail_reg_inst() == n_inst + 1
206 assert capture == ""
207 with capture:
208 del p
209 assert ConstructorStats.detail_reg_inst() == n_inst
210 assert capture == "Releasing parent."
211
212
213def test_keep_alive_constructor(capture):
214 n_inst = ConstructorStats.detail_reg_inst()
215
216 with capture:
217 p = m.Parent(m.Child())
218 assert ConstructorStats.detail_reg_inst() == n_inst + 2
219 assert (
220 capture
221 == """
222 Allocating child.
223 Allocating parent.
224 """
225 )
226 with capture:
227 del p
228 assert ConstructorStats.detail_reg_inst() == n_inst
229 assert (
230 capture
231 == """
232 Releasing parent.
233 Releasing child.
234 """
235 )
236
237
238def test_call_guard():
239 assert m.unguarded_call() == "unguarded"
240 assert m.guarded_call() == "guarded"
241
242 assert m.multiple_guards_correct_order() == "guarded & guarded"
243 assert m.multiple_guards_wrong_order() == "unguarded & guarded"
244
245 if hasattr(m, "with_gil"):
246 assert m.with_gil() == "GIL held"
247 assert m.without_gil() == "GIL released"
Definition: pytypes.h:1200
bool hasattr(handle obj, handle name)
Definition: pytypes.h:517