μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
test_stl.py
Go to the documentation of this file.
1import pytest
2
3from pybind11_tests import ConstructorStats, UserType
4from pybind11_tests import stl as m
5
6
7def test_vector(doc):
8 """std::vector <-> list"""
9 lst = m.cast_vector()
10 assert lst == [1]
11 lst.append(2)
12 assert m.load_vector(lst)
13 assert m.load_vector(tuple(lst))
14
15 assert m.cast_bool_vector() == [True, False]
16 assert m.load_bool_vector([True, False])
17 assert m.load_bool_vector(tuple([True, False]))
18
19 assert doc(m.cast_vector) == "cast_vector() -> List[int]"
20 assert doc(m.load_vector) == "load_vector(arg0: List[int]) -> bool"
21
22 # Test regression caused by 936: pointers to stl containers weren't castable
23 assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
24
25
26def test_deque(doc):
27 """std::deque <-> list"""
28 lst = m.cast_deque()
29 assert lst == [1]
30 lst.append(2)
31 assert m.load_deque(lst)
32 assert m.load_deque(tuple(lst))
33
34
35def test_array(doc):
36 """std::array <-> list"""
37 lst = m.cast_array()
38 assert lst == [1, 2]
39 assert m.load_array(lst)
40 assert m.load_array(tuple(lst))
41
42 assert doc(m.cast_array) == "cast_array() -> List[int[2]]"
43 assert doc(m.load_array) == "load_array(arg0: List[int[2]]) -> bool"
44
45
46def test_valarray(doc):
47 """std::valarray <-> list"""
48 lst = m.cast_valarray()
49 assert lst == [1, 4, 9]
50 assert m.load_valarray(lst)
51 assert m.load_valarray(tuple(lst))
52
53 assert doc(m.cast_valarray) == "cast_valarray() -> List[int]"
54 assert doc(m.load_valarray) == "load_valarray(arg0: List[int]) -> bool"
55
56
57def test_map(doc):
58 """std::map <-> dict"""
59 d = m.cast_map()
60 assert d == {"key": "value"}
61 assert "key" in d
62 d["key2"] = "value2"
63 assert "key2" in d
64 assert m.load_map(d)
65
66 assert doc(m.cast_map) == "cast_map() -> Dict[str, str]"
67 assert doc(m.load_map) == "load_map(arg0: Dict[str, str]) -> bool"
68
69
70def test_set(doc):
71 """std::set <-> set"""
72 s = m.cast_set()
73 assert s == {"key1", "key2"}
74 s.add("key3")
75 assert m.load_set(s)
76 assert m.load_set(frozenset(s))
77
78 assert doc(m.cast_set) == "cast_set() -> Set[str]"
79 assert doc(m.load_set) == "load_set(arg0: Set[str]) -> bool"
80
81
82def test_recursive_casting():
83 """Tests that stl casters preserve lvalue/rvalue context for container values"""
84 assert m.cast_rv_vector() == ["rvalue", "rvalue"]
85 assert m.cast_lv_vector() == ["lvalue", "lvalue"]
86 assert m.cast_rv_array() == ["rvalue", "rvalue", "rvalue"]
87 assert m.cast_lv_array() == ["lvalue", "lvalue"]
88 assert m.cast_rv_map() == {"a": "rvalue"}
89 assert m.cast_lv_map() == {"a": "lvalue", "b": "lvalue"}
90 assert m.cast_rv_nested() == [[[{"b": "rvalue", "c": "rvalue"}], [{"a": "rvalue"}]]]
91 assert m.cast_lv_nested() == {
92 "a": [[["lvalue", "lvalue"]], [["lvalue", "lvalue"]]],
93 "b": [[["lvalue", "lvalue"], ["lvalue", "lvalue"]]],
94 }
95
96 # Issue #853 test case:
97 z = m.cast_unique_ptr_vector()
98 assert z[0].value == 7 and z[1].value == 42
99
100
101def test_move_out_container():
102 """Properties use the `reference_internal` policy by default. If the underlying function
103 returns an rvalue, the policy is automatically changed to `move` to avoid referencing
104 a temporary. In case the return value is a container of user-defined types, the policy
105 also needs to be applied to the elements, not just the container."""
106 c = m.MoveOutContainer()
107 moved_out_list = c.move_list
108 assert [x.value for x in moved_out_list] == [0, 1, 2]
109
110
111@pytest.mark.skipif(not hasattr(m, "has_optional"), reason="no <optional>")
112def test_optional():
113 assert m.double_or_zero(None) == 0
114 assert m.double_or_zero(42) == 84
115 pytest.raises(TypeError, m.double_or_zero, "foo")
116
117 assert m.half_or_none(0) is None
118 assert m.half_or_none(42) == 21
119 pytest.raises(TypeError, m.half_or_none, "foo")
120
121 assert m.test_nullopt() == 42
122 assert m.test_nullopt(None) == 42
123 assert m.test_nullopt(42) == 42
124 assert m.test_nullopt(43) == 43
125
126 assert m.test_no_assign() == 42
127 assert m.test_no_assign(None) == 42
128 assert m.test_no_assign(m.NoAssign(43)) == 43
129 pytest.raises(TypeError, m.test_no_assign, 43)
130
131 assert m.nodefer_none_optional(None)
132
133 holder = m.OptionalHolder()
134 mvalue = holder.member
135 assert mvalue.initialized
136 assert holder.member_initialized()
137
138 props = m.OptionalProperties()
139 assert int(props.access_by_ref) == 42
140 assert int(props.access_by_copy) == 42
141
142
143@pytest.mark.skipif(
144 not hasattr(m, "has_exp_optional"), reason="no <experimental/optional>"
145)
146def test_exp_optional():
147 assert m.double_or_zero_exp(None) == 0
148 assert m.double_or_zero_exp(42) == 84
149 pytest.raises(TypeError, m.double_or_zero_exp, "foo")
150
151 assert m.half_or_none_exp(0) is None
152 assert m.half_or_none_exp(42) == 21
153 pytest.raises(TypeError, m.half_or_none_exp, "foo")
154
155 assert m.test_nullopt_exp() == 42
156 assert m.test_nullopt_exp(None) == 42
157 assert m.test_nullopt_exp(42) == 42
158 assert m.test_nullopt_exp(43) == 43
159
160 assert m.test_no_assign_exp() == 42
161 assert m.test_no_assign_exp(None) == 42
162 assert m.test_no_assign_exp(m.NoAssign(43)) == 43
163 pytest.raises(TypeError, m.test_no_assign_exp, 43)
164
165 holder = m.OptionalExpHolder()
166 mvalue = holder.member
167 assert mvalue.initialized
168 assert holder.member_initialized()
169
170 props = m.OptionalExpProperties()
171 assert int(props.access_by_ref) == 42
172 assert int(props.access_by_copy) == 42
173
174
175@pytest.mark.skipif(not hasattr(m, "has_boost_optional"), reason="no <boost/optional>")
176def test_boost_optional():
177 assert m.double_or_zero_boost(None) == 0
178 assert m.double_or_zero_boost(42) == 84
179 pytest.raises(TypeError, m.double_or_zero_boost, "foo")
180
181 assert m.half_or_none_boost(0) is None
182 assert m.half_or_none_boost(42) == 21
183 pytest.raises(TypeError, m.half_or_none_boost, "foo")
184
185 assert m.test_nullopt_boost() == 42
186 assert m.test_nullopt_boost(None) == 42
187 assert m.test_nullopt_boost(42) == 42
188 assert m.test_nullopt_boost(43) == 43
189
190 assert m.test_no_assign_boost() == 42
191 assert m.test_no_assign_boost(None) == 42
192 assert m.test_no_assign_boost(m.NoAssign(43)) == 43
193 pytest.raises(TypeError, m.test_no_assign_boost, 43)
194
195 holder = m.OptionalBoostHolder()
196 mvalue = holder.member
197 assert mvalue.initialized
198 assert holder.member_initialized()
199
200 props = m.OptionalBoostProperties()
201 assert int(props.access_by_ref) == 42
202 assert int(props.access_by_copy) == 42
203
204
205def test_reference_sensitive_optional():
206 assert m.double_or_zero_refsensitive(None) == 0
207 assert m.double_or_zero_refsensitive(42) == 84
208 pytest.raises(TypeError, m.double_or_zero_refsensitive, "foo")
209
210 assert m.half_or_none_refsensitive(0) is None
211 assert m.half_or_none_refsensitive(42) == 21
212 pytest.raises(TypeError, m.half_or_none_refsensitive, "foo")
213
214 assert m.test_nullopt_refsensitive() == 42
215 assert m.test_nullopt_refsensitive(None) == 42
216 assert m.test_nullopt_refsensitive(42) == 42
217 assert m.test_nullopt_refsensitive(43) == 43
218
219 assert m.test_no_assign_refsensitive() == 42
220 assert m.test_no_assign_refsensitive(None) == 42
221 assert m.test_no_assign_refsensitive(m.NoAssign(43)) == 43
222 pytest.raises(TypeError, m.test_no_assign_refsensitive, 43)
223
224 holder = m.OptionalRefSensitiveHolder()
225 mvalue = holder.member
226 assert mvalue.initialized
227 assert holder.member_initialized()
228
229 props = m.OptionalRefSensitiveProperties()
230 assert int(props.access_by_ref) == 42
231 assert int(props.access_by_copy) == 42
232
233
234@pytest.mark.skipif(not hasattr(m, "has_filesystem"), reason="no <filesystem>")
235def test_fs_path():
236 from pathlib import Path
237
238 class PseudoStrPath:
239 def __fspath__(self):
240 return "foo/bar"
241
242 class PseudoBytesPath:
243 def __fspath__(self):
244 return b"foo/bar"
245
246 assert m.parent_path(Path("foo/bar")) == Path("foo")
247 assert m.parent_path("foo/bar") == Path("foo")
248 assert m.parent_path(b"foo/bar") == Path("foo")
249 assert m.parent_path(PseudoStrPath()) == Path("foo")
250 assert m.parent_path(PseudoBytesPath()) == Path("foo")
251
252
253@pytest.mark.skipif(not hasattr(m, "load_variant"), reason="no <variant>")
254def test_variant(doc):
255 assert m.load_variant(1) == "int"
256 assert m.load_variant("1") == "std::string"
257 assert m.load_variant(1.0) == "double"
258 assert m.load_variant(None) == "std::nullptr_t"
259
260 assert m.load_variant_2pass(1) == "int"
261 assert m.load_variant_2pass(1.0) == "double"
262
263 assert m.cast_variant() == (5, "Hello")
264
265 assert (
266 doc(m.load_variant) == "load_variant(arg0: Union[int, str, float, None]) -> str"
267 )
268
269
270@pytest.mark.skipif(
271 not hasattr(m, "load_monostate_variant"), reason="no std::monostate"
272)
274 assert m.load_monostate_variant(None) == "std::monostate"
275 assert m.load_monostate_variant(1) == "int"
276 assert m.load_monostate_variant("1") == "std::string"
277
278 assert m.cast_monostate_variant() == (None, 5, "Hello")
279
280 assert (
281 doc(m.load_monostate_variant)
282 == "load_monostate_variant(arg0: Union[None, int, str]) -> str"
283 )
284
285
287 """#171: Can't return reference wrappers (or STL structures containing them)"""
288 assert (
289 str(m.return_vec_of_reference_wrapper(UserType(4)))
290 == "[UserType(1), UserType(2), UserType(3), UserType(4)]"
291 )
292
293
295 """Passing nullptr or None to an STL container pointer is not expected to work"""
296 with pytest.raises(TypeError) as excinfo:
297 m.stl_pass_by_pointer() # default value is `nullptr`
298 assert (
299 msg(excinfo.value)
300 == """
301 stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
302 1. (v: List[int] = None) -> List[int]
303
304 Invoked with:
305 """
306 )
307
308 with pytest.raises(TypeError) as excinfo:
309 m.stl_pass_by_pointer(None)
310 assert (
311 msg(excinfo.value)
312 == """
313 stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
314 1. (v: List[int] = None) -> List[int]
315
316 Invoked with: None
317 """
318 )
319
320 assert m.stl_pass_by_pointer([1, 2, 3]) == [1, 2, 3]
321
322
324 """Trying convert `list` to a `std::vector`, or vice versa, without including
325 <pybind11/stl.h> should result in a helpful suggestion in the error message"""
326 import pybind11_cross_module_tests as cm
327
328 expected_message = (
329 "Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,\n"
330 "<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic\n"
331 "conversions are optional and require extra headers to be included\n"
332 "when compiling your pybind11 module."
333 )
334
335 with pytest.raises(TypeError) as excinfo:
336 cm.missing_header_arg([1.0, 2.0, 3.0])
337 assert expected_message in str(excinfo.value)
338
339 with pytest.raises(TypeError) as excinfo:
340 cm.missing_header_return()
341 assert expected_message in str(excinfo.value)
342
343
345 """Check if a string is NOT implicitly converted to a list, which was the
346 behavior before fix of issue #1258"""
347 assert m.func_with_string_or_vector_string_arg_overload(("A", "B")) == 2
348 assert m.func_with_string_or_vector_string_arg_overload(["A", "B"]) == 2
349 assert m.func_with_string_or_vector_string_arg_overload("A") == 3
350
351
353 cstats = ConstructorStats.get(m.Placeholder)
354 assert cstats.alive() == 0
355 r = m.test_stl_ownership()
356 assert len(r) == 1
357 del r
358 assert cstats.alive() == 0
359
360
362 assert m.array_cast_sequence((1, 2, 3)) == [1, 2, 3]
363
364
365def test_issue_1561():
366 """check fix for issue #1561"""
367 bar = m.Issue1561Outer()
368 bar.list = [m.Issue1561Inner("bar")]
369 bar.list
370 assert bar.list[0].data == "bar"
371
372
374 # Add `while True:` for manual leak checking.
375 v = m.return_vector_bool_raw_ptr()
376 assert isinstance(v, list)
377 assert len(v) == 4513
static ConstructorStats & get(std::type_index type)
Definition: pytypes.h:1200
bool hasattr(handle obj, handle name)
Definition: pytypes.h:517
bool isinstance(handle obj)
\rst Return true if obj is an instance of T.
Definition: pytypes.h:489
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2002
def test_return_vector_bool_raw_ptr()
Definition: test_stl.py:354
def test_function_with_string_and_vector_string_arg()
Definition: test_stl.py:325
def test_issue_1561()
Definition: test_stl.py:346
def test_variant_monostate(doc)
Definition: test_stl.py:273
def test_stl_pass_by_pointer(msg)
Definition: test_stl.py:275
def test_vec_of_reference_wrapper()
Definition: test_stl.py:267
def test_array_cast_sequence()
Definition: test_stl.py:342
def test_stl_ownership()
Definition: test_stl.py:333
def test_missing_header_message()
Definition: test_stl.py:304
Annotation for documentation.
Definition: attr.h:41