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


gtsam
Author(s):
autogenerated on Sun Dec 22 2024 04:15:58