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


gtsam
Author(s):
autogenerated on Thu Jul 4 2024 03:06:03