cppyabm  1.0.17
An agent-based library to integrate C++ and Python
test_call_policies.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 import pytest
3 
4 import env # noqa: F401
5 
6 from pybind11_tests import call_policies as m
7 from pybind11_tests import ConstructorStats
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 
51  n_inst = ConstructorStats.detail_reg_inst()
52  with capture:
53  p = m.Parent()
54  assert capture == "Allocating parent."
55  with capture:
56  p.returnChild()
57  assert ConstructorStats.detail_reg_inst() == n_inst + 1
58  assert (
59  capture
60  == """
61  Allocating child.
62  Releasing child.
63  """
64  )
65  with capture:
66  del p
67  assert ConstructorStats.detail_reg_inst() == n_inst
68  assert capture == "Releasing parent."
69 
70  with capture:
71  p = m.Parent()
72  assert capture == "Allocating parent."
73  with capture:
74  p.returnChildKeepAlive()
75  assert ConstructorStats.detail_reg_inst() == n_inst + 2
76  assert capture == "Allocating child."
77  with capture:
78  del p
79  assert ConstructorStats.detail_reg_inst() == n_inst
80  assert (
81  capture
82  == """
83  Releasing parent.
84  Releasing child.
85  """
86  )
87 
88 
89 # https://foss.heptapod.net/pypy/pypy/-/issues/2447
90 @pytest.mark.xfail("env.PYPY", reason="_PyObject_GetDictPtr is unimplemented")
91 def test_alive_gc(capture):
92  n_inst = ConstructorStats.detail_reg_inst()
93  p = m.ParentGC()
94  p.addChildKeepAlive(m.Child())
95  assert ConstructorStats.detail_reg_inst() == n_inst + 2
96  lst = [p]
97  lst.append(lst) # creates a circular reference
98  with capture:
99  del p, lst
100  assert ConstructorStats.detail_reg_inst() == n_inst
101  assert (
102  capture
103  == """
104  Releasing parent.
105  Releasing child.
106  """
107  )
108 
109 
111  class Derived(m.Parent):
112  pass
113 
114  n_inst = ConstructorStats.detail_reg_inst()
115  p = Derived()
116  p.addChildKeepAlive(m.Child())
117  assert ConstructorStats.detail_reg_inst() == n_inst + 2
118  lst = [p]
119  lst.append(lst) # creates a circular reference
120  with capture:
121  del p, lst
122  assert ConstructorStats.detail_reg_inst() == n_inst
123  assert (
124  capture
125  == """
126  Releasing parent.
127  Releasing child.
128  """
129  )
130 
131 
133  class Derived(m.Parent, m.Child):
134  def __init__(self):
135  m.Parent.__init__(self)
136  m.Child.__init__(self)
137 
138  n_inst = ConstructorStats.detail_reg_inst()
139  p = Derived()
140  p.addChildKeepAlive(m.Child())
141  # +3 rather than +2 because Derived corresponds to two registered instances
142  assert ConstructorStats.detail_reg_inst() == n_inst + 3
143  lst = [p]
144  lst.append(lst) # creates a circular reference
145  with capture:
146  del p, lst
147  assert ConstructorStats.detail_reg_inst() == n_inst
148  assert (
149  capture
150  == """
151  Releasing parent.
152  Releasing child.
153  Releasing child.
154  """
155  )
156 
157 
158 def test_return_none(capture):
159  n_inst = ConstructorStats.detail_reg_inst()
160  with capture:
161  p = m.Parent()
162  assert capture == "Allocating parent."
163  with capture:
164  p.returnNullChildKeepAliveChild()
165  assert ConstructorStats.detail_reg_inst() == n_inst + 1
166  assert capture == ""
167  with capture:
168  del p
169  assert ConstructorStats.detail_reg_inst() == n_inst
170  assert capture == "Releasing parent."
171 
172  with capture:
173  p = m.Parent()
174  assert capture == "Allocating parent."
175  with capture:
176  p.returnNullChildKeepAliveParent()
177  assert ConstructorStats.detail_reg_inst() == n_inst + 1
178  assert capture == ""
179  with capture:
180  del p
181  assert ConstructorStats.detail_reg_inst() == n_inst
182  assert capture == "Releasing parent."
183 
184 
186  n_inst = ConstructorStats.detail_reg_inst()
187 
188  with capture:
189  p = m.Parent(m.Child())
190  assert ConstructorStats.detail_reg_inst() == n_inst + 2
191  assert (
192  capture
193  == """
194  Allocating child.
195  Allocating parent.
196  """
197  )
198  with capture:
199  del p
200  assert ConstructorStats.detail_reg_inst() == n_inst
201  assert (
202  capture
203  == """
204  Releasing parent.
205  Releasing child.
206  """
207  )
208 
209 
211  assert m.unguarded_call() == "unguarded"
212  assert m.guarded_call() == "guarded"
213 
214  assert m.multiple_guards_correct_order() == "guarded & guarded"
215  assert m.multiple_guards_wrong_order() == "unguarded & guarded"
216 
217  if hasattr(m, "with_gil"):
218  assert m.with_gil() == "GIL held"
219  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:132
test_call_policies.test_keep_alive_return_value
def test_keep_alive_return_value(capture)
Definition: test_call_policies.py:50
hasattr
bool hasattr(handle obj, handle name)
Definition: pytypes.h:405
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:210
test_call_policies.test_keep_alive_constructor
def test_keep_alive_constructor(capture)
Definition: test_call_policies.py:185
test_call_policies.test_alive_gc_derived
def test_alive_gc_derived(capture)
Definition: test_call_policies.py:110
test_call_policies.test_return_none
def test_return_none(capture)
Definition: test_call_policies.py:158
test_call_policies.test_alive_gc
def test_alive_gc(capture)
Definition: test_call_policies.py:91