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