test_smart_ptr.py
Go to the documentation of this file.
1 import pytest
2 
3 m = pytest.importorskip("pybind11_tests.smart_ptr")
4 from pybind11_tests import ConstructorStats # noqa: E402
5 
6 
7 def test_smart_ptr(capture):
8  # Object1
9  for i, o in enumerate(
10  [m.make_object_1(), m.make_object_2(), m.MyObject1(3)], start=1
11  ):
12  assert o.getRefCount() == 1
13  with capture:
14  m.print_object_1(o)
15  m.print_object_2(o)
16  m.print_object_3(o)
17  m.print_object_4(o)
18  assert capture == f"MyObject1[{i}]\n" * 4
19 
20  for i, o in enumerate(
21  [m.make_myobject1_1(), m.make_myobject1_2(), m.MyObject1(6), 7], start=4
22  ):
23  print(o)
24  with capture:
25  if not isinstance(o, int):
26  m.print_object_1(o)
27  m.print_object_2(o)
28  m.print_object_3(o)
29  m.print_object_4(o)
30  m.print_myobject1_1(o)
31  m.print_myobject1_2(o)
32  m.print_myobject1_3(o)
33  m.print_myobject1_4(o)
34 
35  times = 4 if isinstance(o, int) else 8
36  assert capture == f"MyObject1[{i}]\n" * times
37 
38  cstats = ConstructorStats.get(m.MyObject1)
39  assert cstats.alive() == 0
40  expected_values = [f"MyObject1[{i}]" for i in range(1, 7)] + ["MyObject1[7]"] * 4
41  assert cstats.values() == expected_values
42  assert cstats.default_constructions == 0
43  assert cstats.copy_constructions == 0
44  # assert cstats.move_constructions >= 0 # Doesn't invoke any
45  assert cstats.copy_assignments == 0
46  assert cstats.move_assignments == 0
47 
48  # Object2
49  for i, o in zip(
50  [8, 6, 7], [m.MyObject2(8), m.make_myobject2_1(), m.make_myobject2_2()]
51  ):
52  print(o)
53  with capture:
54  m.print_myobject2_1(o)
55  m.print_myobject2_2(o)
56  m.print_myobject2_3(o)
57  m.print_myobject2_4(o)
58  assert capture == f"MyObject2[{i}]\n" * 4
59 
60  cstats = ConstructorStats.get(m.MyObject2)
61  assert cstats.alive() == 1
62  o = None
63  assert cstats.alive() == 0
64  assert cstats.values() == ["MyObject2[8]", "MyObject2[6]", "MyObject2[7]"]
65  assert cstats.default_constructions == 0
66  assert cstats.copy_constructions == 0
67  # assert cstats.move_constructions >= 0 # Doesn't invoke any
68  assert cstats.copy_assignments == 0
69  assert cstats.move_assignments == 0
70 
71  # Object3
72  for i, o in zip(
73  [9, 8, 9], [m.MyObject3(9), m.make_myobject3_1(), m.make_myobject3_2()]
74  ):
75  print(o)
76  with capture:
77  m.print_myobject3_1(o)
78  m.print_myobject3_2(o)
79  m.print_myobject3_3(o)
80  m.print_myobject3_4(o)
81  assert capture == f"MyObject3[{i}]\n" * 4
82 
83  cstats = ConstructorStats.get(m.MyObject3)
84  assert cstats.alive() == 1
85  o = None
86  assert cstats.alive() == 0
87  assert cstats.values() == ["MyObject3[9]", "MyObject3[8]", "MyObject3[9]"]
88  assert cstats.default_constructions == 0
89  assert cstats.copy_constructions == 0
90  # assert cstats.move_constructions >= 0 # Doesn't invoke any
91  assert cstats.copy_assignments == 0
92  assert cstats.move_assignments == 0
93 
94  # Object
95  cstats = ConstructorStats.get(m.Object)
96  assert cstats.alive() == 0
97  assert cstats.values() == []
98  assert cstats.default_constructions == 10
99  assert cstats.copy_constructions == 0
100  # assert cstats.move_constructions >= 0 # Doesn't invoke any
101  assert cstats.copy_assignments == 0
102  assert cstats.move_assignments == 0
103 
104  # ref<>
105  cstats = m.cstats_ref()
106  assert cstats.alive() == 0
107  assert cstats.values() == ["from pointer"] * 10
108  assert cstats.default_constructions == 30
109  assert cstats.copy_constructions == 12
110  # assert cstats.move_constructions >= 0 # Doesn't invoke any
111  assert cstats.copy_assignments == 30
112  assert cstats.move_assignments == 0
113 
114 
116  assert m.test_object1_refcounting()
117 
118 
120  o = m.MyObject4(23)
121  assert o.value == 23
122  cstats = ConstructorStats.get(m.MyObject4)
123  assert cstats.alive() == 1
124  del o
125  assert cstats.alive() == 1
126  m.MyObject4.cleanup_all_instances()
127  assert cstats.alive() == 0
128 
129 
131  o = m.MyObject4a(23)
132  assert o.value == 23
133  cstats = ConstructorStats.get(m.MyObject4a)
134  assert cstats.alive() == 1
135  del o
136  assert cstats.alive() == 1
137  m.MyObject4a.cleanup_all_instances()
138  assert cstats.alive() == 0
139 
140 
142  m.MyObject4a(0)
143  o = m.MyObject4b(23)
144  assert o.value == 23
145  cstats4a = ConstructorStats.get(m.MyObject4a)
146  assert cstats4a.alive() == 2
147  cstats4b = ConstructorStats.get(m.MyObject4b)
148  assert cstats4b.alive() == 1
149  del o
150  assert cstats4a.alive() == 1 # Should now only be one leftover
151  assert cstats4b.alive() == 0 # Should be deleted
152  m.MyObject4a.cleanup_all_instances()
153  assert cstats4a.alive() == 0
154  assert cstats4b.alive() == 0
155 
156 
158  o = m.MyObject5(5)
159  assert o.value == 5
160  cstats = ConstructorStats.get(m.MyObject5)
161  assert cstats.alive() == 1
162  del o
163  assert cstats.alive() == 0
164 
165 
167  s = m.SharedPtrRef()
168  stats = ConstructorStats.get(m.A)
169  assert stats.alive() == 2
170 
171  ref = s.ref # init_holder_helper(holder_ptr=false, owned=false)
172  assert stats.alive() == 2
173  assert s.set_ref(ref)
174  with pytest.raises(RuntimeError) as excinfo:
175  assert s.set_holder(ref)
176  assert "Unable to cast from non-held to held instance" in str(excinfo.value)
177 
178  copy = s.copy # init_holder_helper(holder_ptr=false, owned=true)
179  assert stats.alive() == 3
180  assert s.set_ref(copy)
181  assert s.set_holder(copy)
182 
183  holder_ref = s.holder_ref # init_holder_helper(holder_ptr=true, owned=false)
184  assert stats.alive() == 3
185  assert s.set_ref(holder_ref)
186  assert s.set_holder(holder_ref)
187 
188  holder_copy = s.holder_copy # init_holder_helper(holder_ptr=true, owned=true)
189  assert stats.alive() == 3
190  assert s.set_ref(holder_copy)
191  assert s.set_holder(holder_copy)
192 
193  del ref, copy, holder_ref, holder_copy, s
194  assert stats.alive() == 0
195 
196 
198  s = m.SharedFromThisRef()
199  stats = ConstructorStats.get(m.B)
200  assert stats.alive() == 2
201 
202  ref = s.ref # init_holder_helper(holder_ptr=false, owned=false, bad_wp=false)
203  assert stats.alive() == 2
204  assert s.set_ref(ref)
205  assert s.set_holder(
206  ref
207  ) # std::enable_shared_from_this can create a holder from a reference
208 
209  bad_wp = s.bad_wp # init_holder_helper(holder_ptr=false, owned=false, bad_wp=true)
210  assert stats.alive() == 2
211  assert s.set_ref(bad_wp)
212  with pytest.raises(RuntimeError) as excinfo:
213  assert s.set_holder(bad_wp)
214  assert "Unable to cast from non-held to held instance" in str(excinfo.value)
215 
216  copy = s.copy # init_holder_helper(holder_ptr=false, owned=true, bad_wp=false)
217  assert stats.alive() == 3
218  assert s.set_ref(copy)
219  assert s.set_holder(copy)
220 
221  holder_ref = (
222  s.holder_ref
223  ) # init_holder_helper(holder_ptr=true, owned=false, bad_wp=false)
224  assert stats.alive() == 3
225  assert s.set_ref(holder_ref)
226  assert s.set_holder(holder_ref)
227 
228  holder_copy = (
229  s.holder_copy
230  ) # init_holder_helper(holder_ptr=true, owned=true, bad_wp=false)
231  assert stats.alive() == 3
232  assert s.set_ref(holder_copy)
233  assert s.set_holder(holder_copy)
234 
235  del ref, bad_wp, copy, holder_ref, holder_copy, s
236  assert stats.alive() == 0
237 
238  z = m.SharedFromThisVirt.get()
239  y = m.SharedFromThisVirt.get()
240  assert y is z
241 
242 
244  a = m.TypeWithMoveOnlyHolder.make()
245  b = m.TypeWithMoveOnlyHolder.make_as_object()
246  stats = ConstructorStats.get(m.TypeWithMoveOnlyHolder)
247  assert stats.alive() == 2
248  del b
249  assert stats.alive() == 1
250  del a
251  assert stats.alive() == 0
252 
253 
255  # this test must not throw exception from c++
256  a = m.TypeForHolderWithAddressOf.make()
257  a.print_object_1()
258  a.print_object_2()
259  a.print_object_3()
260  a.print_object_4()
261 
262  stats = ConstructorStats.get(m.TypeForHolderWithAddressOf)
263  assert stats.alive() == 1
264 
265  np = m.TypeForHolderWithAddressOf.make()
266  assert stats.alive() == 2
267  del a
268  assert stats.alive() == 1
269  del np
270  assert stats.alive() == 0
271 
272  b = m.TypeForHolderWithAddressOf.make()
273  c = b
274  assert b.get() is c.get()
275  assert stats.alive() == 1
276 
277  del b
278  assert stats.alive() == 1
279 
280  del c
281  assert stats.alive() == 0
282 
283 
285  a = m.TypeForMoveOnlyHolderWithAddressOf.make()
286  a.print_object()
287 
288  stats = ConstructorStats.get(m.TypeForMoveOnlyHolderWithAddressOf)
289  assert stats.alive() == 1
290 
291  a.value = 42
292  assert a.value == 42
293 
294  del a
295  assert stats.alive() == 0
296 
297 
299  instance = m.HeldByDefaultHolder()
300  with pytest.raises(RuntimeError) as excinfo:
301  m.HeldByDefaultHolder.load_shared_ptr(instance)
302  assert (
303  "Unable to load a custom holder type from a "
304  "default-holder instance" in str(excinfo.value)
305  )
306 
307 
309  """#187: issue involving std::shared_ptr<> return value policy & garbage collection"""
310  el = m.ElementList()
311  for i in range(10):
312  el.add(m.ElementA(i))
313  pytest.gc_collect()
314  for i, v in enumerate(el.get()):
315  assert i == v.value()
test_smart_ptr.test_unique_nodelete4a
def test_unique_nodelete4a()
Definition: test_smart_ptr.py:130
Eigen::internal::print
EIGEN_STRONG_INLINE Packet4f print(const Packet4f &a)
Definition: NEON/PacketMath.h:3115
test_smart_ptr.test_smart_ptr
def test_smart_ptr(capture)
Definition: test_smart_ptr.py:7
test_smart_ptr.test_holder_with_addressof_operator
def test_holder_with_addressof_operator()
Definition: test_smart_ptr.py:254
gtsam::range
Double_ range(const Point2_ &p, const Point2_ &q)
Definition: slam/expressions.h:30
test_smart_ptr.test_smart_ptr_refcounting
def test_smart_ptr_refcounting()
Definition: test_smart_ptr.py:115
isinstance
bool isinstance(handle obj)
Definition: pytypes.h:825
test_smart_ptr.test_shared_ptr_and_references
def test_shared_ptr_and_references()
Definition: test_smart_ptr.py:166
test_smart_ptr.test_move_only_holder
def test_move_only_holder()
Definition: test_smart_ptr.py:243
test_smart_ptr.test_smart_ptr_from_default
def test_smart_ptr_from_default()
Definition: test_smart_ptr.py:298
test_smart_ptr.test_unique_nodelete
def test_unique_nodelete()
Definition: test_smart_ptr.py:119
str
Definition: pytypes.h:1524
ConstructorStats::get
static ConstructorStats & get(std::type_index type)
Definition: constructor_stats.h:163
test_smart_ptr.test_move_only_holder_with_addressof_operator
def test_move_only_holder_with_addressof_operator()
Definition: test_smart_ptr.py:284
test_smart_ptr.test_large_holder
def test_large_holder()
Definition: test_smart_ptr.py:157
test_smart_ptr.test_shared_ptr_gc
def test_shared_ptr_gc()
Definition: test_smart_ptr.py:308
test_smart_ptr.test_shared_ptr_from_this_and_references
def test_shared_ptr_from_this_and_references()
Definition: test_smart_ptr.py:197
test_smart_ptr.test_unique_deleter
def test_unique_deleter()
Definition: test_smart_ptr.py:141


gtsam
Author(s):
autogenerated on Tue Jun 25 2024 03:05:31