github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/tests/test_builtin_casters.py (about)

     1  import sys
     2  
     3  import pytest
     4  
     5  import env
     6  from pybind11_tests import IncType, UserType
     7  from pybind11_tests import builtin_casters as m
     8  
     9  
    10  def test_simple_string():
    11      assert m.string_roundtrip("const char *") == "const char *"
    12  
    13  
    14  def test_unicode_conversion():
    15      """Tests unicode conversion and error reporting."""
    16      assert m.good_utf8_string() == "Say utf8β€½ πŸŽ‚ 𝐀"
    17      assert m.good_utf16_string() == "bβ€½πŸŽ‚π€z"
    18      assert m.good_utf32_string() == "aπ€πŸŽ‚β€½z"
    19      assert m.good_wchar_string() == "aβΈ˜π€z"
    20      if hasattr(m, "has_u8string"):
    21          assert m.good_utf8_u8string() == "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)
    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() == "Γ©"
    42      assert m.u16_ibang() == "β€½"
    43      assert m.u32_mathbfA() == "𝐀"
    44      assert m.wchar_heart() == "β™₯"
    45      if hasattr(m, "has_u8string"):
    46          assert m.u8_char8_Z() == "Z"
    47  
    48  
    49  def test_single_char_arguments():
    50      """Tests failures for passing invalid inputs to char-accepting functions"""
    51  
    52      def toobig_message(r):
    53          return f"Character code point not in range({r:#x})"
    54  
    55      toolong_message = "Expected a character, but multi-character string found"
    56  
    57      assert m.ord_char("a") == 0x61  # simple ASCII
    58      assert m.ord_char_lv("b") == 0x62
    59      assert (
    60          m.ord_char("Γ©") == 0xE9
    61      )  # requires 2 bytes in utf-8, but can be stuffed in a char
    62      with pytest.raises(ValueError) as excinfo:
    63          assert m.ord_char("Δ€") == 0x100  # requires 2 bytes, doesn't fit in a char
    64      assert str(excinfo.value) == toobig_message(0x100)
    65      with pytest.raises(ValueError) as excinfo:
    66          assert m.ord_char("ab")
    67      assert str(excinfo.value) == toolong_message
    68  
    69      assert m.ord_char16("a") == 0x61
    70      assert m.ord_char16("Γ©") == 0xE9
    71      assert m.ord_char16_lv("Γͺ") == 0xEA
    72      assert m.ord_char16("Δ€") == 0x100
    73      assert m.ord_char16("β€½") == 0x203D
    74      assert m.ord_char16("β™₯") == 0x2665
    75      assert m.ord_char16_lv("β™‘") == 0x2661
    76      with pytest.raises(ValueError) as excinfo:
    77          assert m.ord_char16("πŸŽ‚") == 0x1F382  # requires surrogate pair
    78      assert str(excinfo.value) == toobig_message(0x10000)
    79      with pytest.raises(ValueError) as excinfo:
    80          assert m.ord_char16("aa")
    81      assert str(excinfo.value) == toolong_message
    82  
    83      assert m.ord_char32("a") == 0x61
    84      assert m.ord_char32("Γ©") == 0xE9
    85      assert m.ord_char32("Δ€") == 0x100
    86      assert m.ord_char32("β€½") == 0x203D
    87      assert m.ord_char32("β™₯") == 0x2665
    88      assert m.ord_char32("πŸŽ‚") == 0x1F382
    89      with pytest.raises(ValueError) as excinfo:
    90          assert m.ord_char32("aa")
    91      assert str(excinfo.value) == toolong_message
    92  
    93      assert m.ord_wchar("a") == 0x61
    94      assert m.ord_wchar("Γ©") == 0xE9
    95      assert m.ord_wchar("Δ€") == 0x100
    96      assert m.ord_wchar("β€½") == 0x203D
    97      assert m.ord_wchar("β™₯") == 0x2665
    98      if m.wchar_size == 2:
    99          with pytest.raises(ValueError) as excinfo:
   100              assert m.ord_wchar("πŸŽ‚") == 0x1F382  # requires surrogate pair
   101          assert str(excinfo.value) == toobig_message(0x10000)
   102      else:
   103          assert m.ord_wchar("πŸŽ‚") == 0x1F382
   104      with pytest.raises(ValueError) as excinfo:
   105          assert m.ord_wchar("aa")
   106      assert str(excinfo.value) == toolong_message
   107  
   108      if hasattr(m, "has_u8string"):
   109          assert m.ord_char8("a") == 0x61  # simple ASCII
   110          assert m.ord_char8_lv("b") == 0x62
   111          assert (
   112              m.ord_char8("Γ©") == 0xE9
   113          )  # requires 2 bytes in utf-8, but can be stuffed in a char
   114          with pytest.raises(ValueError) as excinfo:
   115              assert m.ord_char8("Δ€") == 0x100  # requires 2 bytes, doesn't fit in a char
   116          assert str(excinfo.value) == toobig_message(0x100)
   117          with pytest.raises(ValueError) as excinfo:
   118              assert m.ord_char8("ab")
   119          assert str(excinfo.value) == toolong_message
   120  
   121  
   122  def test_bytes_to_string():
   123      """Tests the ability to pass bytes to C++ string-accepting functions.  Note that this is
   124      one-way: the only way to return bytes to Python is via the pybind11::bytes class."""
   125      # Issue #816
   126  
   127      assert m.strlen(b"hi") == 2
   128      assert m.string_length(b"world") == 5
   129      assert m.string_length("a\x00b".encode()) == 3
   130      assert m.strlen("a\x00b".encode()) == 1  # C-string limitation
   131  
   132      # passing in a utf8 encoded string should work
   133      assert m.string_length("πŸ’©".encode()) == 4
   134  
   135  
   136  def test_bytearray_to_string():
   137      """Tests the ability to pass bytearray to C++ string-accepting functions"""
   138      assert m.string_length(bytearray(b"Hi")) == 2
   139      assert m.strlen(bytearray(b"bytearray")) == 9
   140      assert m.string_length(bytearray()) == 0
   141      assert m.string_length(bytearray("🦜", "utf-8", "strict")) == 4
   142      assert m.string_length(bytearray(b"\x80")) == 1
   143  
   144  
   145  @pytest.mark.skipif(not hasattr(m, "has_string_view"), reason="no <string_view>")
   146  def test_string_view(capture):
   147      """Tests support for C++17 string_view arguments and return values"""
   148      assert m.string_view_chars("Hi") == [72, 105]
   149      assert m.string_view_chars("Hi πŸŽ‚") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]
   150      assert m.string_view16_chars("Hi πŸŽ‚") == [72, 105, 32, 0xD83C, 0xDF82]
   151      assert m.string_view32_chars("Hi πŸŽ‚") == [72, 105, 32, 127874]
   152      if hasattr(m, "has_u8string"):
   153          assert m.string_view8_chars("Hi") == [72, 105]
   154          assert m.string_view8_chars("Hi πŸŽ‚") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]
   155  
   156      assert m.string_view_return() == "utf8 secret πŸŽ‚"
   157      assert m.string_view16_return() == "utf16 secret πŸŽ‚"
   158      assert m.string_view32_return() == "utf32 secret πŸŽ‚"
   159      if hasattr(m, "has_u8string"):
   160          assert m.string_view8_return() == "utf8 secret πŸŽ‚"
   161  
   162      with capture:
   163          m.string_view_print("Hi")
   164          m.string_view_print("utf8 πŸŽ‚")
   165          m.string_view16_print("utf16 πŸŽ‚")
   166          m.string_view32_print("utf32 πŸŽ‚")
   167      assert (
   168          capture
   169          == """
   170          Hi 2
   171          utf8 πŸŽ‚ 9
   172          utf16 πŸŽ‚ 8
   173          utf32 πŸŽ‚ 7
   174      """
   175      )
   176      if hasattr(m, "has_u8string"):
   177          with capture:
   178              m.string_view8_print("Hi")
   179              m.string_view8_print("utf8 πŸŽ‚")
   180          assert (
   181              capture
   182              == """
   183              Hi 2
   184              utf8 πŸŽ‚ 9
   185          """
   186          )
   187  
   188      with capture:
   189          m.string_view_print("Hi, ascii")
   190          m.string_view_print("Hi, utf8 πŸŽ‚")
   191          m.string_view16_print("Hi, utf16 πŸŽ‚")
   192          m.string_view32_print("Hi, utf32 πŸŽ‚")
   193      assert (
   194          capture
   195          == """
   196          Hi, ascii 9
   197          Hi, utf8 πŸŽ‚ 13
   198          Hi, utf16 πŸŽ‚ 12
   199          Hi, utf32 πŸŽ‚ 11
   200      """
   201      )
   202      if hasattr(m, "has_u8string"):
   203          with capture:
   204              m.string_view8_print("Hi, ascii")
   205              m.string_view8_print("Hi, utf8 πŸŽ‚")
   206          assert (
   207              capture
   208              == """
   209              Hi, ascii 9
   210              Hi, utf8 πŸŽ‚ 13
   211          """
   212          )
   213  
   214      assert m.string_view_bytes() == b"abc \x80\x80 def"
   215      assert m.string_view_str() == "abc β€½ def"
   216      assert m.string_view_from_bytes("abc β€½ def".encode()) == "abc β€½ def"
   217      if hasattr(m, "has_u8string"):
   218          assert m.string_view8_str() == "abc β€½ def"
   219      assert m.string_view_memoryview() == "Have some πŸŽ‚".encode()
   220  
   221      assert m.bytes_from_type_with_both_operator_string_and_string_view() == b"success"
   222      assert m.str_from_type_with_both_operator_string_and_string_view() == "success"
   223  
   224  
   225  def test_integer_casting():
   226      """Issue #929 - out-of-range integer values shouldn't be accepted"""
   227      assert m.i32_str(-1) == "-1"
   228      assert m.i64_str(-1) == "-1"
   229      assert m.i32_str(2000000000) == "2000000000"
   230      assert m.u32_str(2000000000) == "2000000000"
   231      assert m.i64_str(-999999999999) == "-999999999999"
   232      assert m.u64_str(999999999999) == "999999999999"
   233  
   234      with pytest.raises(TypeError) as excinfo:
   235          m.u32_str(-1)
   236      assert "incompatible function arguments" in str(excinfo.value)
   237      with pytest.raises(TypeError) as excinfo:
   238          m.u64_str(-1)
   239      assert "incompatible function arguments" in str(excinfo.value)
   240      with pytest.raises(TypeError) as excinfo:
   241          m.i32_str(-3000000000)
   242      assert "incompatible function arguments" in str(excinfo.value)
   243      with pytest.raises(TypeError) as excinfo:
   244          m.i32_str(3000000000)
   245      assert "incompatible function arguments" in str(excinfo.value)
   246  
   247  
   248  def test_int_convert():
   249      class Int:
   250          def __int__(self):
   251              return 42
   252  
   253      class NotInt:
   254          pass
   255  
   256      class Float:
   257          def __float__(self):
   258              return 41.99999
   259  
   260      class Index:
   261          def __index__(self):
   262              return 42
   263  
   264      class IntAndIndex:
   265          def __int__(self):
   266              return 42
   267  
   268          def __index__(self):
   269              return 0
   270  
   271      class RaisingTypeErrorOnIndex:
   272          def __index__(self):
   273              raise TypeError
   274  
   275          def __int__(self):
   276              return 42
   277  
   278      class RaisingValueErrorOnIndex:
   279          def __index__(self):
   280              raise ValueError
   281  
   282          def __int__(self):
   283              return 42
   284  
   285      convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert
   286  
   287      def requires_conversion(v):
   288          pytest.raises(TypeError, noconvert, v)
   289  
   290      def cant_convert(v):
   291          pytest.raises(TypeError, convert, v)
   292  
   293      assert convert(7) == 7
   294      assert noconvert(7) == 7
   295      cant_convert(3.14159)
   296      # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
   297      # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
   298      if (3, 8) <= sys.version_info < (3, 10) and env.CPYTHON:
   299          with env.deprecated_call():
   300              assert convert(Int()) == 42
   301      else:
   302          assert convert(Int()) == 42
   303      requires_conversion(Int())
   304      cant_convert(NotInt())
   305      cant_convert(Float())
   306  
   307      # Before Python 3.8, `PyLong_AsLong` does not pick up on `obj.__index__`,
   308      # but pybind11 "backports" this behavior.
   309      assert convert(Index()) == 42
   310      assert noconvert(Index()) == 42
   311      assert convert(IntAndIndex()) == 0  # Fishy; `int(DoubleThought)` == 42
   312      assert noconvert(IntAndIndex()) == 0
   313      assert convert(RaisingTypeErrorOnIndex()) == 42
   314      requires_conversion(RaisingTypeErrorOnIndex())
   315      assert convert(RaisingValueErrorOnIndex()) == 42
   316      requires_conversion(RaisingValueErrorOnIndex())
   317  
   318  
   319  def test_numpy_int_convert():
   320      np = pytest.importorskip("numpy")
   321  
   322      convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert
   323  
   324      def require_implicit(v):
   325          pytest.raises(TypeError, noconvert, v)
   326  
   327      # `np.intc` is an alias that corresponds to a C++ `int`
   328      assert convert(np.intc(42)) == 42
   329      assert noconvert(np.intc(42)) == 42
   330  
   331      # The implicit conversion from np.float32 is undesirable but currently accepted.
   332      # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
   333      # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
   334      # https://github.com/pybind/pybind11/issues/3408
   335      if (3, 8) <= sys.version_info < (3, 10) and env.CPYTHON:
   336          with env.deprecated_call():
   337              assert convert(np.float32(3.14159)) == 3
   338      else:
   339          assert convert(np.float32(3.14159)) == 3
   340      require_implicit(np.float32(3.14159))
   341  
   342  
   343  def test_tuple(doc):
   344      """std::pair <-> tuple & std::tuple <-> tuple"""
   345      assert m.pair_passthrough((True, "test")) == ("test", True)
   346      assert m.tuple_passthrough((True, "test", 5)) == (5, "test", True)
   347      # Any sequence can be cast to a std::pair or std::tuple
   348      assert m.pair_passthrough([True, "test"]) == ("test", True)
   349      assert m.tuple_passthrough([True, "test", 5]) == (5, "test", True)
   350      assert m.empty_tuple() == ()
   351  
   352      assert (
   353          doc(m.pair_passthrough)
   354          == """
   355          pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]
   356  
   357          Return a pair in reversed order
   358      """
   359      )
   360      assert (
   361          doc(m.tuple_passthrough)
   362          == """
   363          tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]
   364  
   365          Return a triple in reversed order
   366      """
   367      )
   368  
   369      assert m.rvalue_pair() == ("rvalue", "rvalue")
   370      assert m.lvalue_pair() == ("lvalue", "lvalue")
   371      assert m.rvalue_tuple() == ("rvalue", "rvalue", "rvalue")
   372      assert m.lvalue_tuple() == ("lvalue", "lvalue", "lvalue")
   373      assert m.rvalue_nested() == ("rvalue", ("rvalue", ("rvalue", "rvalue")))
   374      assert m.lvalue_nested() == ("lvalue", ("lvalue", ("lvalue", "lvalue")))
   375  
   376      assert m.int_string_pair() == (2, "items")
   377  
   378  
   379  def test_builtins_cast_return_none():
   380      """Casters produced with PYBIND11_TYPE_CASTER() should convert nullptr to None"""
   381      assert m.return_none_string() is None
   382      assert m.return_none_char() is None
   383      assert m.return_none_bool() is None
   384      assert m.return_none_int() is None
   385      assert m.return_none_float() is None
   386      assert m.return_none_pair() is None
   387  
   388  
   389  def test_none_deferred():
   390      """None passed as various argument types should defer to other overloads"""
   391      assert not m.defer_none_cstring("abc")
   392      assert m.defer_none_cstring(None)
   393      assert not m.defer_none_custom(UserType())
   394      assert m.defer_none_custom(None)
   395      assert m.nodefer_none_void(None)
   396  
   397  
   398  def test_void_caster():
   399      assert m.load_nullptr_t(None) is None
   400      assert m.cast_nullptr_t() is None
   401  
   402  
   403  def test_reference_wrapper():
   404      """std::reference_wrapper for builtin and user types"""
   405      assert m.refwrap_builtin(42) == 420
   406      assert m.refwrap_usertype(UserType(42)) == 42
   407      assert m.refwrap_usertype_const(UserType(42)) == 42
   408  
   409      with pytest.raises(TypeError) as excinfo:
   410          m.refwrap_builtin(None)
   411      assert "incompatible function arguments" in str(excinfo.value)
   412  
   413      with pytest.raises(TypeError) as excinfo:
   414          m.refwrap_usertype(None)
   415      assert "incompatible function arguments" in str(excinfo.value)
   416  
   417      assert m.refwrap_lvalue().value == 1
   418      assert m.refwrap_lvalue_const().value == 1
   419  
   420      a1 = m.refwrap_list(copy=True)
   421      a2 = m.refwrap_list(copy=True)
   422      assert [x.value for x in a1] == [2, 3]
   423      assert [x.value for x in a2] == [2, 3]
   424      assert not a1[0] is a2[0] and not a1[1] is a2[1]
   425  
   426      b1 = m.refwrap_list(copy=False)
   427      b2 = m.refwrap_list(copy=False)
   428      assert [x.value for x in b1] == [1, 2]
   429      assert [x.value for x in b2] == [1, 2]
   430      assert b1[0] is b2[0] and b1[1] is b2[1]
   431  
   432      assert m.refwrap_iiw(IncType(5)) == 5
   433      assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]
   434  
   435  
   436  def test_complex_cast():
   437      """std::complex casts"""
   438      assert m.complex_cast(1) == "1.0"
   439      assert m.complex_cast(2j) == "(0.0, 2.0)"
   440  
   441  
   442  def test_bool_caster():
   443      """Test bool caster implicit conversions."""
   444      convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
   445  
   446      def require_implicit(v):
   447          pytest.raises(TypeError, noconvert, v)
   448  
   449      def cant_convert(v):
   450          pytest.raises(TypeError, convert, v)
   451  
   452      # straight up bool
   453      assert convert(True) is True
   454      assert convert(False) is False
   455      assert noconvert(True) is True
   456      assert noconvert(False) is False
   457  
   458      # None requires implicit conversion
   459      require_implicit(None)
   460      assert convert(None) is False
   461  
   462      class A:
   463          def __init__(self, x):
   464              self.x = x
   465  
   466          def __nonzero__(self):
   467              return self.x
   468  
   469          def __bool__(self):
   470              return self.x
   471  
   472      class B:
   473          pass
   474  
   475      # Arbitrary objects are not accepted
   476      cant_convert(object())
   477      cant_convert(B())
   478  
   479      # Objects with __nonzero__ / __bool__ defined can be converted
   480      require_implicit(A(True))
   481      assert convert(A(True)) is True
   482      assert convert(A(False)) is False
   483  
   484  
   485  def test_numpy_bool():
   486      np = pytest.importorskip("numpy")
   487  
   488      convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
   489  
   490      def cant_convert(v):
   491          pytest.raises(TypeError, convert, v)
   492  
   493      # np.bool_ is not considered implicit
   494      assert convert(np.bool_(True)) is True
   495      assert convert(np.bool_(False)) is False
   496      assert noconvert(np.bool_(True)) is True
   497      assert noconvert(np.bool_(False)) is False
   498      cant_convert(np.zeros(2, dtype="int"))
   499  
   500  
   501  def test_int_long():
   502      assert isinstance(m.int_cast(), int)
   503      assert isinstance(m.long_cast(), int)
   504      assert isinstance(m.longlong_cast(), int)
   505  
   506  
   507  def test_void_caster_2():
   508      assert m.test_void_caster()
   509  
   510  
   511  def test_const_ref_caster():
   512      """Verifies that const-ref is propagated through type_caster cast_op.
   513      The returned ConstRefCasted type is a minimal type that is constructed to
   514      reference the casting mode used.
   515      """
   516      x = False
   517      assert m.takes(x) == 1
   518      assert m.takes_move(x) == 1
   519  
   520      assert m.takes_ptr(x) == 3
   521      assert m.takes_ref(x) == 2
   522      assert m.takes_ref_wrap(x) == 2
   523  
   524      assert m.takes_const_ptr(x) == 5
   525      assert m.takes_const_ref(x) == 4
   526      assert m.takes_const_ref_wrap(x) == 4