test_builtin_casters.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 builtin_casters as m
7 from pybind11_tests import UserType, IncType
8 
9 
11  assert m.string_roundtrip("const char *") == "const char *"
12 
13 
15  """Tests unicode conversion and error reporting."""
16  assert m.good_utf8_string() == u"Say utf8β€½ πŸŽ‚ 𝐀"
17  assert m.good_utf16_string() == u"bβ€½πŸŽ‚π€z"
18  assert m.good_utf32_string() == u"aπ€πŸŽ‚β€½z"
19  assert m.good_wchar_string() == u"aβΈ˜π€z"
20  if hasattr(m, "has_u8string"):
21  assert m.good_utf8_u8string() == u"Say utf8β€½ πŸŽ‚ 𝐀"
22 
23  with pytest.raises(UnicodeDecodeError):
24  m.bad_utf8_string()
25 
26  with pytest.raises(UnicodeDecodeError):
27  m.bad_utf16_string()
28 
29  # These are provided only if they actually fail (they don't when 32-bit and under Python 2.7)
30  if hasattr(m, "bad_utf32_string"):
31  with pytest.raises(UnicodeDecodeError):
32  m.bad_utf32_string()
33  if hasattr(m, "bad_wchar_string"):
34  with pytest.raises(UnicodeDecodeError):
35  m.bad_wchar_string()
36  if hasattr(m, "has_u8string"):
37  with pytest.raises(UnicodeDecodeError):
38  m.bad_utf8_u8string()
39 
40  assert m.u8_Z() == 'Z'
41  assert m.u8_eacute() == u'Γ©'
42  assert m.u16_ibang() == u'β€½'
43  assert m.u32_mathbfA() == u'𝐀'
44  assert m.wchar_heart() == u'β™₯'
45  if hasattr(m, "has_u8string"):
46  assert m.u8_char8_Z() == 'Z'
47 
48 
50  """Tests failures for passing invalid inputs to char-accepting functions"""
51  def toobig_message(r):
52  return "Character code point not in range({0:#x})".format(r)
53  toolong_message = "Expected a character, but multi-character string found"
54 
55  assert m.ord_char(u'a') == 0x61 # simple ASCII
56  assert m.ord_char_lv(u'b') == 0x62
57  assert m.ord_char(u'Γ©') == 0xE9 # requires 2 bytes in utf-8, but can be stuffed in a char
58  with pytest.raises(ValueError) as excinfo:
59  assert m.ord_char(u'Δ€') == 0x100 # requires 2 bytes, doesn't fit in a char
60  assert str(excinfo.value) == toobig_message(0x100)
61  with pytest.raises(ValueError) as excinfo:
62  assert m.ord_char(u'ab')
63  assert str(excinfo.value) == toolong_message
64 
65  assert m.ord_char16(u'a') == 0x61
66  assert m.ord_char16(u'Γ©') == 0xE9
67  assert m.ord_char16_lv(u'Γͺ') == 0xEA
68  assert m.ord_char16(u'Δ€') == 0x100
69  assert m.ord_char16(u'β€½') == 0x203d
70  assert m.ord_char16(u'β™₯') == 0x2665
71  assert m.ord_char16_lv(u'β™‘') == 0x2661
72  with pytest.raises(ValueError) as excinfo:
73  assert m.ord_char16(u'πŸŽ‚') == 0x1F382 # requires surrogate pair
74  assert str(excinfo.value) == toobig_message(0x10000)
75  with pytest.raises(ValueError) as excinfo:
76  assert m.ord_char16(u'aa')
77  assert str(excinfo.value) == toolong_message
78 
79  assert m.ord_char32(u'a') == 0x61
80  assert m.ord_char32(u'Γ©') == 0xE9
81  assert m.ord_char32(u'Δ€') == 0x100
82  assert m.ord_char32(u'β€½') == 0x203d
83  assert m.ord_char32(u'β™₯') == 0x2665
84  assert m.ord_char32(u'πŸŽ‚') == 0x1F382
85  with pytest.raises(ValueError) as excinfo:
86  assert m.ord_char32(u'aa')
87  assert str(excinfo.value) == toolong_message
88 
89  assert m.ord_wchar(u'a') == 0x61
90  assert m.ord_wchar(u'Γ©') == 0xE9
91  assert m.ord_wchar(u'Δ€') == 0x100
92  assert m.ord_wchar(u'β€½') == 0x203d
93  assert m.ord_wchar(u'β™₯') == 0x2665
94  if m.wchar_size == 2:
95  with pytest.raises(ValueError) as excinfo:
96  assert m.ord_wchar(u'πŸŽ‚') == 0x1F382 # requires surrogate pair
97  assert str(excinfo.value) == toobig_message(0x10000)
98  else:
99  assert m.ord_wchar(u'πŸŽ‚') == 0x1F382
100  with pytest.raises(ValueError) as excinfo:
101  assert m.ord_wchar(u'aa')
102  assert str(excinfo.value) == toolong_message
103 
104  if hasattr(m, "has_u8string"):
105  assert m.ord_char8(u'a') == 0x61 # simple ASCII
106  assert m.ord_char8_lv(u'b') == 0x62
107  assert m.ord_char8(u'Γ©') == 0xE9 # requires 2 bytes in utf-8, but can be stuffed in a char
108  with pytest.raises(ValueError) as excinfo:
109  assert m.ord_char8(u'Δ€') == 0x100 # requires 2 bytes, doesn't fit in a char
110  assert str(excinfo.value) == toobig_message(0x100)
111  with pytest.raises(ValueError) as excinfo:
112  assert m.ord_char8(u'ab')
113  assert str(excinfo.value) == toolong_message
114 
115 
117  """Tests the ability to pass bytes to C++ string-accepting functions. Note that this is
118  one-way: the only way to return bytes to Python is via the pybind11::bytes class."""
119  # Issue #816
120 
121  def to_bytes(s):
122  b = s if env.PY2 else s.encode("utf8")
123  assert isinstance(b, bytes)
124  return b
125 
126  assert m.strlen(to_bytes("hi")) == 2
127  assert m.string_length(to_bytes("world")) == 5
128  assert m.string_length(to_bytes("a\x00b")) == 3
129  assert m.strlen(to_bytes("a\x00b")) == 1 # C-string limitation
130 
131  # passing in a utf8 encoded string should work
132  assert m.string_length(u'πŸ’©'.encode("utf8")) == 4
133 
134 
135 @pytest.mark.skipif(not hasattr(m, "has_string_view"), reason="no <string_view>")
136 def test_string_view(capture):
137  """Tests support for C++17 string_view arguments and return values"""
138  assert m.string_view_chars("Hi") == [72, 105]
139  assert m.string_view_chars("Hi πŸŽ‚") == [72, 105, 32, 0xf0, 0x9f, 0x8e, 0x82]
140  assert m.string_view16_chars(u"Hi πŸŽ‚") == [72, 105, 32, 0xd83c, 0xdf82]
141  assert m.string_view32_chars(u"Hi πŸŽ‚") == [72, 105, 32, 127874]
142  if hasattr(m, "has_u8string"):
143  assert m.string_view8_chars("Hi") == [72, 105]
144  assert m.string_view8_chars(u"Hi πŸŽ‚") == [72, 105, 32, 0xf0, 0x9f, 0x8e, 0x82]
145 
146  assert m.string_view_return() == u"utf8 secret πŸŽ‚"
147  assert m.string_view16_return() == u"utf16 secret πŸŽ‚"
148  assert m.string_view32_return() == u"utf32 secret πŸŽ‚"
149  if hasattr(m, "has_u8string"):
150  assert m.string_view8_return() == u"utf8 secret πŸŽ‚"
151 
152  with capture:
153  m.string_view_print("Hi")
154  m.string_view_print("utf8 πŸŽ‚")
155  m.string_view16_print(u"utf16 πŸŽ‚")
156  m.string_view32_print(u"utf32 πŸŽ‚")
157  assert capture == u"""
158  Hi 2
159  utf8 πŸŽ‚ 9
160  utf16 πŸŽ‚ 8
161  utf32 πŸŽ‚ 7
162  """
163  if hasattr(m, "has_u8string"):
164  with capture:
165  m.string_view8_print("Hi")
166  m.string_view8_print(u"utf8 πŸŽ‚")
167  assert capture == u"""
168  Hi 2
169  utf8 πŸŽ‚ 9
170  """
171 
172  with capture:
173  m.string_view_print("Hi, ascii")
174  m.string_view_print("Hi, utf8 πŸŽ‚")
175  m.string_view16_print(u"Hi, utf16 πŸŽ‚")
176  m.string_view32_print(u"Hi, utf32 πŸŽ‚")
177  assert capture == u"""
178  Hi, ascii 9
179  Hi, utf8 πŸŽ‚ 13
180  Hi, utf16 πŸŽ‚ 12
181  Hi, utf32 πŸŽ‚ 11
182  """
183  if hasattr(m, "has_u8string"):
184  with capture:
185  m.string_view8_print("Hi, ascii")
186  m.string_view8_print(u"Hi, utf8 πŸŽ‚")
187  assert capture == u"""
188  Hi, ascii 9
189  Hi, utf8 πŸŽ‚ 13
190  """
191 
192 
194  """Issue #929 - out-of-range integer values shouldn't be accepted"""
195  assert m.i32_str(-1) == "-1"
196  assert m.i64_str(-1) == "-1"
197  assert m.i32_str(2000000000) == "2000000000"
198  assert m.u32_str(2000000000) == "2000000000"
199  if env.PY2:
200  assert m.i32_str(long(-1)) == "-1" # noqa: F821 undefined name 'long'
201  assert m.i64_str(long(-1)) == "-1" # noqa: F821 undefined name 'long'
202  assert m.i64_str(long(-999999999999)) == "-999999999999" # noqa: F821 undefined name
203  assert m.u64_str(long(999999999999)) == "999999999999" # noqa: F821 undefined name 'long'
204  else:
205  assert m.i64_str(-999999999999) == "-999999999999"
206  assert m.u64_str(999999999999) == "999999999999"
207 
208  with pytest.raises(TypeError) as excinfo:
209  m.u32_str(-1)
210  assert "incompatible function arguments" in str(excinfo.value)
211  with pytest.raises(TypeError) as excinfo:
212  m.u64_str(-1)
213  assert "incompatible function arguments" in str(excinfo.value)
214  with pytest.raises(TypeError) as excinfo:
215  m.i32_str(-3000000000)
216  assert "incompatible function arguments" in str(excinfo.value)
217  with pytest.raises(TypeError) as excinfo:
218  m.i32_str(3000000000)
219  assert "incompatible function arguments" in str(excinfo.value)
220 
221  if env.PY2:
222  with pytest.raises(TypeError) as excinfo:
223  m.u32_str(long(-1)) # noqa: F821 undefined name 'long'
224  assert "incompatible function arguments" in str(excinfo.value)
225  with pytest.raises(TypeError) as excinfo:
226  m.u64_str(long(-1)) # noqa: F821 undefined name 'long'
227  assert "incompatible function arguments" in str(excinfo.value)
228 
229 
230 def test_tuple(doc):
231  """std::pair <-> tuple & std::tuple <-> tuple"""
232  assert m.pair_passthrough((True, "test")) == ("test", True)
233  assert m.tuple_passthrough((True, "test", 5)) == (5, "test", True)
234  # Any sequence can be cast to a std::pair or std::tuple
235  assert m.pair_passthrough([True, "test"]) == ("test", True)
236  assert m.tuple_passthrough([True, "test", 5]) == (5, "test", True)
237  assert m.empty_tuple() == ()
238 
239  assert doc(m.pair_passthrough) == """
240  pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]
241 
242  Return a pair in reversed order
243  """
244  assert doc(m.tuple_passthrough) == """
245  tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]
246 
247  Return a triple in reversed order
248  """
249 
250  assert m.rvalue_pair() == ("rvalue", "rvalue")
251  assert m.lvalue_pair() == ("lvalue", "lvalue")
252  assert m.rvalue_tuple() == ("rvalue", "rvalue", "rvalue")
253  assert m.lvalue_tuple() == ("lvalue", "lvalue", "lvalue")
254  assert m.rvalue_nested() == ("rvalue", ("rvalue", ("rvalue", "rvalue")))
255  assert m.lvalue_nested() == ("lvalue", ("lvalue", ("lvalue", "lvalue")))
256 
257  assert m.int_string_pair() == (2, "items")
258 
259 
261  """Casters produced with PYBIND11_TYPE_CASTER() should convert nullptr to None"""
262  assert m.return_none_string() is None
263  assert m.return_none_char() is None
264  assert m.return_none_bool() is None
265  assert m.return_none_int() is None
266  assert m.return_none_float() is None
267  assert m.return_none_pair() is None
268 
269 
271  """None passed as various argument types should defer to other overloads"""
272  assert not m.defer_none_cstring("abc")
273  assert m.defer_none_cstring(None)
274  assert not m.defer_none_custom(UserType())
275  assert m.defer_none_custom(None)
276  assert m.nodefer_none_void(None)
277 
278 
280  assert m.load_nullptr_t(None) is None
281  assert m.cast_nullptr_t() is None
282 
283 
285  """std::reference_wrapper for builtin and user types"""
286  assert m.refwrap_builtin(42) == 420
287  assert m.refwrap_usertype(UserType(42)) == 42
288 
289  with pytest.raises(TypeError) as excinfo:
290  m.refwrap_builtin(None)
291  assert "incompatible function arguments" in str(excinfo.value)
292 
293  with pytest.raises(TypeError) as excinfo:
294  m.refwrap_usertype(None)
295  assert "incompatible function arguments" in str(excinfo.value)
296 
297  a1 = m.refwrap_list(copy=True)
298  a2 = m.refwrap_list(copy=True)
299  assert [x.value for x in a1] == [2, 3]
300  assert [x.value for x in a2] == [2, 3]
301  assert not a1[0] is a2[0] and not a1[1] is a2[1]
302 
303  b1 = m.refwrap_list(copy=False)
304  b2 = m.refwrap_list(copy=False)
305  assert [x.value for x in b1] == [1, 2]
306  assert [x.value for x in b2] == [1, 2]
307  assert b1[0] is b2[0] and b1[1] is b2[1]
308 
309  assert m.refwrap_iiw(IncType(5)) == 5
310  assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]
311 
312 
314  """std::complex casts"""
315  assert m.complex_cast(1) == "1.0"
316  assert m.complex_cast(2j) == "(0.0, 2.0)"
317 
318 
320  """Test bool caster implicit conversions."""
321  convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
322 
323  def require_implicit(v):
324  pytest.raises(TypeError, noconvert, v)
325 
326  def cant_convert(v):
327  pytest.raises(TypeError, convert, v)
328 
329  # straight up bool
330  assert convert(True) is True
331  assert convert(False) is False
332  assert noconvert(True) is True
333  assert noconvert(False) is False
334 
335  # None requires implicit conversion
336  require_implicit(None)
337  assert convert(None) is False
338 
339  class A(object):
340  def __init__(self, x):
341  self.x = x
342 
343  def __nonzero__(self):
344  return self.x
345 
346  def __bool__(self):
347  return self.x
348 
349  class B(object):
350  pass
351 
352  # Arbitrary objects are not accepted
353  cant_convert(object())
354  cant_convert(B())
355 
356  # Objects with __nonzero__ / __bool__ defined can be converted
357  require_implicit(A(True))
358  assert convert(A(True)) is True
359  assert convert(A(False)) is False
360 
361 
363  np = pytest.importorskip("numpy")
364 
365  convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
366 
367  def cant_convert(v):
368  pytest.raises(TypeError, convert, v)
369 
370  # np.bool_ is not considered implicit
371  assert convert(np.bool_(True)) is True
372  assert convert(np.bool_(False)) is False
373  assert noconvert(np.bool_(True)) is True
374  assert noconvert(np.bool_(False)) is False
375  cant_convert(np.zeros(2, dtype='int'))
376 
377 
379  """In Python 2, a C++ int should return a Python int rather than long
380  if possible: longs are not always accepted where ints are used (such
381  as the argument to sys.exit()). A C++ long long is always a Python
382  long."""
383 
384  import sys
385  must_be_long = type(getattr(sys, 'maxint', 1) + 1)
386  assert isinstance(m.int_cast(), int)
387  assert isinstance(m.long_cast(), int)
388  assert isinstance(m.longlong_cast(), must_be_long)
389 
390 
392  assert m.test_void_caster()
bool hasattr(handle obj, handle name)
Definition: pytypes.h:403
Annotation for documentation.
Definition: attr.h:33
bool isinstance(handle obj)
Definition: pytypes.h:384
Definition: pytypes.h:928
bool convert(const int &y)
object getattr(handle obj, handle name)
Definition: pytypes.h:419
Definition: pytypes.h:897


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:46:03