from __future__ import annotations import sys import pytest import env from pybind11_tests import IncType, UserType from pybind11_tests import builtin_casters as m def test_simple_string(): assert m.string_roundtrip("const char *") == "const char *" def test_unicode_conversion(): """Tests unicode conversion and error reporting.""" assert m.good_utf8_string() == "Say utf8β€½ πŸŽ‚ 𝐀" assert m.good_utf16_string() == "bβ€½πŸŽ‚π€z" assert m.good_utf32_string() == "aπ€πŸŽ‚β€½z" assert m.good_wchar_string() == "aβΈ˜π€z" if hasattr(m, "has_u8string"): assert m.good_utf8_u8string() == "Say utf8β€½ πŸŽ‚ 𝐀" with pytest.raises(UnicodeDecodeError): m.bad_utf8_string() with pytest.raises(UnicodeDecodeError): m.bad_utf16_string() # These are provided only if they actually fail (they don't when 32-bit) if hasattr(m, "bad_utf32_string"): with pytest.raises(UnicodeDecodeError): m.bad_utf32_string() if hasattr(m, "bad_wchar_string"): with pytest.raises(UnicodeDecodeError): m.bad_wchar_string() if hasattr(m, "has_u8string"): with pytest.raises(UnicodeDecodeError): m.bad_utf8_u8string() assert m.u8_Z() == "Z" assert m.u8_eacute() == "Γ©" assert m.u16_ibang() == "β€½" assert m.u32_mathbfA() == "𝐀" assert m.wchar_heart() == "β™₯" if hasattr(m, "has_u8string"): assert m.u8_char8_Z() == "Z" def test_single_char_arguments(): """Tests failures for passing invalid inputs to char-accepting functions""" def toobig_message(r): return f"Character code point not in range({r:#x})" toolong_message = "Expected a character, but multi-character string found" assert m.ord_char("a") == 0x61 # simple ASCII assert m.ord_char_lv("b") == 0x62 assert ( m.ord_char("Γ©") == 0xE9 ) # requires 2 bytes in utf-8, but can be stuffed in a char with pytest.raises(ValueError) as excinfo: assert m.ord_char("Δ€") == 0x100 # requires 2 bytes, doesn't fit in a char assert str(excinfo.value) == toobig_message(0x100) with pytest.raises(ValueError) as excinfo: assert m.ord_char("ab") assert str(excinfo.value) == toolong_message assert m.ord_char16("a") == 0x61 assert m.ord_char16("Γ©") == 0xE9 assert m.ord_char16_lv("Γͺ") == 0xEA assert m.ord_char16("Δ€") == 0x100 assert m.ord_char16("β€½") == 0x203D assert m.ord_char16("β™₯") == 0x2665 assert m.ord_char16_lv("β™‘") == 0x2661 with pytest.raises(ValueError) as excinfo: assert m.ord_char16("πŸŽ‚") == 0x1F382 # requires surrogate pair assert str(excinfo.value) == toobig_message(0x10000) with pytest.raises(ValueError) as excinfo: assert m.ord_char16("aa") assert str(excinfo.value) == toolong_message assert m.ord_char32("a") == 0x61 assert m.ord_char32("Γ©") == 0xE9 assert m.ord_char32("Δ€") == 0x100 assert m.ord_char32("β€½") == 0x203D assert m.ord_char32("β™₯") == 0x2665 assert m.ord_char32("πŸŽ‚") == 0x1F382 with pytest.raises(ValueError) as excinfo: assert m.ord_char32("aa") assert str(excinfo.value) == toolong_message assert m.ord_wchar("a") == 0x61 assert m.ord_wchar("Γ©") == 0xE9 assert m.ord_wchar("Δ€") == 0x100 assert m.ord_wchar("β€½") == 0x203D assert m.ord_wchar("β™₯") == 0x2665 if m.wchar_size == 2: with pytest.raises(ValueError) as excinfo: assert m.ord_wchar("πŸŽ‚") == 0x1F382 # requires surrogate pair assert str(excinfo.value) == toobig_message(0x10000) else: assert m.ord_wchar("πŸŽ‚") == 0x1F382 with pytest.raises(ValueError) as excinfo: assert m.ord_wchar("aa") assert str(excinfo.value) == toolong_message if hasattr(m, "has_u8string"): assert m.ord_char8("a") == 0x61 # simple ASCII assert m.ord_char8_lv("b") == 0x62 assert ( m.ord_char8("Γ©") == 0xE9 ) # requires 2 bytes in utf-8, but can be stuffed in a char with pytest.raises(ValueError) as excinfo: assert m.ord_char8("Δ€") == 0x100 # requires 2 bytes, doesn't fit in a char assert str(excinfo.value) == toobig_message(0x100) with pytest.raises(ValueError) as excinfo: assert m.ord_char8("ab") assert str(excinfo.value) == toolong_message def test_bytes_to_string(): """Tests the ability to pass bytes to C++ string-accepting functions. Note that this is one-way: the only way to return bytes to Python is via the pybind11::bytes class.""" # Issue #816 assert m.strlen(b"hi") == 2 assert m.string_length(b"world") == 5 assert m.string_length(b"a\x00b") == 3 assert m.strlen(b"a\x00b") == 1 # C-string limitation # passing in a utf8 encoded string should work assert m.string_length("πŸ’©".encode()) == 4 def test_bytearray_to_string(): """Tests the ability to pass bytearray to C++ string-accepting functions""" assert m.string_length(bytearray(b"Hi")) == 2 assert m.strlen(bytearray(b"bytearray")) == 9 assert m.string_length(bytearray()) == 0 assert m.string_length(bytearray("🦜", "utf-8", "strict")) == 4 assert m.string_length(bytearray(b"\x80")) == 1 @pytest.mark.skipif(not hasattr(m, "has_string_view"), reason="no ") def test_string_view(capture): """Tests support for C++17 string_view arguments and return values""" assert m.string_view_chars("Hi") == [72, 105] assert m.string_view_chars("Hi πŸŽ‚") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82] assert m.string_view16_chars("Hi πŸŽ‚") == [72, 105, 32, 0xD83C, 0xDF82] assert m.string_view32_chars("Hi πŸŽ‚") == [72, 105, 32, 127874] if hasattr(m, "has_u8string"): assert m.string_view8_chars("Hi") == [72, 105] assert m.string_view8_chars("Hi πŸŽ‚") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82] assert m.string_view_return() == "utf8 secret πŸŽ‚" assert m.string_view16_return() == "utf16 secret πŸŽ‚" assert m.string_view32_return() == "utf32 secret πŸŽ‚" if hasattr(m, "has_u8string"): assert m.string_view8_return() == "utf8 secret πŸŽ‚" with capture: m.string_view_print("Hi") m.string_view_print("utf8 πŸŽ‚") m.string_view16_print("utf16 πŸŽ‚") m.string_view32_print("utf32 πŸŽ‚") assert ( capture == """ Hi 2 utf8 πŸŽ‚ 9 utf16 πŸŽ‚ 8 utf32 πŸŽ‚ 7 """ ) if hasattr(m, "has_u8string"): with capture: m.string_view8_print("Hi") m.string_view8_print("utf8 πŸŽ‚") assert ( capture == """ Hi 2 utf8 πŸŽ‚ 9 """ ) with capture: m.string_view_print("Hi, ascii") m.string_view_print("Hi, utf8 πŸŽ‚") m.string_view16_print("Hi, utf16 πŸŽ‚") m.string_view32_print("Hi, utf32 πŸŽ‚") assert ( capture == """ Hi, ascii 9 Hi, utf8 πŸŽ‚ 13 Hi, utf16 πŸŽ‚ 12 Hi, utf32 πŸŽ‚ 11 """ ) if hasattr(m, "has_u8string"): with capture: m.string_view8_print("Hi, ascii") m.string_view8_print("Hi, utf8 πŸŽ‚") assert ( capture == """ Hi, ascii 9 Hi, utf8 πŸŽ‚ 13 """ ) assert m.string_view_bytes() == b"abc \x80\x80 def" assert m.string_view_str() == "abc β€½ def" assert m.string_view_from_bytes("abc β€½ def".encode()) == "abc β€½ def" if hasattr(m, "has_u8string"): assert m.string_view8_str() == "abc β€½ def" assert m.string_view_memoryview() == "Have some πŸŽ‚".encode() assert m.bytes_from_type_with_both_operator_string_and_string_view() == b"success" assert m.str_from_type_with_both_operator_string_and_string_view() == "success" def test_integer_casting(): """Issue #929 - out-of-range integer values shouldn't be accepted""" assert m.i32_str(-1) == "-1" assert m.i64_str(-1) == "-1" assert m.i32_str(2000000000) == "2000000000" assert m.u32_str(2000000000) == "2000000000" assert m.i64_str(-999999999999) == "-999999999999" assert m.u64_str(999999999999) == "999999999999" with pytest.raises(TypeError) as excinfo: m.u32_str(-1) assert "incompatible function arguments" in str(excinfo.value) with pytest.raises(TypeError) as excinfo: m.u64_str(-1) assert "incompatible function arguments" in str(excinfo.value) with pytest.raises(TypeError) as excinfo: m.i32_str(-3000000000) assert "incompatible function arguments" in str(excinfo.value) with pytest.raises(TypeError) as excinfo: m.i32_str(3000000000) assert "incompatible function arguments" in str(excinfo.value) def test_int_convert(doc): class Int: def __int__(self): return 42 class NotInt: pass class Float: def __float__(self): return 41.99999 class Index: def __index__(self): return 42 class IntAndIndex: def __int__(self): return 42 def __index__(self): return 0 class RaisingTypeErrorOnIndex: def __index__(self): raise TypeError def __int__(self): return 42 class RaisingValueErrorOnIndex: def __index__(self): raise ValueError def __int__(self): return 42 convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert assert ( doc(convert) == "int_passthrough(arg0: typing.SupportsInt | typing.SupportsIndex) -> int" ) assert doc(noconvert) == "int_passthrough_noconvert(arg0: int) -> int" def requires_conversion(v): pytest.raises(TypeError, noconvert, v) def cant_convert(v): pytest.raises(TypeError, convert, v) assert convert(7) == 7 assert noconvert(7) == 7 cant_convert(3.14159) # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar) # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7) if sys.version_info < (3, 10) and env.CPYTHON: with pytest.deprecated_call(): assert convert(Int()) == 42 else: assert convert(Int()) == 42 requires_conversion(Int()) cant_convert(NotInt()) cant_convert(Float()) # Before Python 3.8, `PyLong_AsLong` does not pick up on `obj.__index__`, # but pybind11 "backports" this behavior. assert convert(Index()) == 42 assert isinstance(convert(Index()), int) assert noconvert(Index()) == 42 assert convert(IntAndIndex()) == 0 # Fishy; `int(DoubleThought)` == 42 assert noconvert(IntAndIndex()) == 0 assert convert(RaisingTypeErrorOnIndex()) == 42 requires_conversion(RaisingTypeErrorOnIndex()) assert convert(RaisingValueErrorOnIndex()) == 42 requires_conversion(RaisingValueErrorOnIndex()) class IndexReturnsFloat: def __index__(self): return 3.14 # noqa: PLE0305 Wrong: should return int class IntReturnsFloat: def __int__(self): return 3.14 # Wrong: should return int class IndexFloatIntInt: def __index__(self): return 3.14 # noqa: PLE0305 Wrong: should return int def __int__(self): return 42 # Correct: returns int class IndexIntIntFloat: def __index__(self): return 42 # Correct: returns int def __int__(self): return 3.14 # Wrong: should return int class IndexFloatIntFloat: def __index__(self): return 3.14 # noqa: PLE0305 Wrong: should return int def __int__(self): return 2.71 # Wrong: should return int cant_convert(IndexReturnsFloat()) requires_conversion(IndexReturnsFloat()) cant_convert(IntReturnsFloat()) requires_conversion(IntReturnsFloat()) assert convert(IndexFloatIntInt()) == 42 # convert: __index__ fails, uses __int__ requires_conversion(IndexFloatIntInt()) # noconvert: __index__ fails, no fallback assert convert(IndexIntIntFloat()) == 42 # convert: __index__ succeeds assert noconvert(IndexIntIntFloat()) == 42 # noconvert: __index__ succeeds cant_convert(IndexFloatIntFloat()) # convert mode rejects (both fail) requires_conversion(IndexFloatIntFloat()) # noconvert mode also rejects def test_float_convert(doc): class Int: def __int__(self): return -5 class Index: def __index__(self) -> int: return -7 class Float: def __float__(self): return 41.45 convert, noconvert = m.float_passthrough, m.float_passthrough_noconvert assert ( doc(convert) == "float_passthrough(arg0: typing.SupportsFloat | typing.SupportsIndex) -> float" ) assert doc(noconvert) == "float_passthrough_noconvert(arg0: float) -> float" def requires_conversion(v): pytest.raises(TypeError, noconvert, v) def cant_convert(v): pytest.raises(TypeError, convert, v) requires_conversion(Float()) requires_conversion(Index()) assert pytest.approx(convert(Float())) == 41.45 assert pytest.approx(convert(Index())) == -7.0 assert isinstance(convert(Float()), float) assert pytest.approx(convert(3)) == 3.0 assert pytest.approx(noconvert(3)) == 3.0 cant_convert(Int()) def test_numpy_int_convert(): np = pytest.importorskip("numpy") convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert def require_implicit(v): pytest.raises(TypeError, noconvert, v) # `np.intc` is an alias that corresponds to a C++ `int` assert convert(np.intc(42)) == 42 assert noconvert(np.intc(42)) == 42 # The implicit conversion from np.float32 is undesirable but currently accepted. # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar) # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7) # https://github.com/pybind/pybind11/issues/3408 if (3, 8) <= sys.version_info < (3, 10) and env.CPYTHON: with pytest.deprecated_call(): assert convert(np.float32(3.14159)) == 3 else: assert convert(np.float32(3.14159)) == 3 require_implicit(np.float32(3.14159)) def test_tuple(doc): """std::pair <-> tuple & std::tuple <-> tuple""" assert m.pair_passthrough((True, "test")) == ("test", True) assert m.tuple_passthrough((True, "test", 5)) == (5, "test", True) # Any sequence can be cast to a std::pair or std::tuple assert m.pair_passthrough([True, "test"]) == ("test", True) assert m.tuple_passthrough([True, "test", 5]) == (5, "test", True) assert m.empty_tuple() == () assert ( doc(m.pair_passthrough) == """ pair_passthrough(arg0: tuple[bool, str]) -> tuple[str, bool] Return a pair in reversed order """ ) assert ( doc(m.tuple_passthrough) == """ tuple_passthrough(arg0: tuple[bool, str, typing.SupportsInt | typing.SupportsIndex]) -> tuple[int, str, bool] Return a triple in reversed order """ ) assert doc(m.empty_tuple) == """empty_tuple() -> tuple[()]""" assert m.rvalue_pair() == ("rvalue", "rvalue") assert m.lvalue_pair() == ("lvalue", "lvalue") assert m.rvalue_tuple() == ("rvalue", "rvalue", "rvalue") assert m.lvalue_tuple() == ("lvalue", "lvalue", "lvalue") assert m.rvalue_nested() == ("rvalue", ("rvalue", ("rvalue", "rvalue"))) assert m.lvalue_nested() == ("lvalue", ("lvalue", ("lvalue", "lvalue"))) assert m.int_string_pair() == (2, "items") def test_builtins_cast_return_none(): """Casters produced with PYBIND11_TYPE_CASTER() should convert nullptr to None""" assert m.return_none_string() is None assert m.return_none_char() is None assert m.return_none_bool() is None assert m.return_none_int() is None assert m.return_none_float() is None assert m.return_none_pair() is None def test_none_deferred(): """None passed as various argument types should defer to other overloads""" assert not m.defer_none_cstring("abc") assert m.defer_none_cstring(None) assert not m.defer_none_custom(UserType()) assert m.defer_none_custom(None) assert m.nodefer_none_void(None) def test_void_caster(): assert m.load_nullptr_t(None) is None assert m.cast_nullptr_t() is None def test_reference_wrapper(): """std::reference_wrapper for builtin and user types""" assert m.refwrap_builtin(42) == 420 assert m.refwrap_usertype(UserType(42)) == 42 assert m.refwrap_usertype_const(UserType(42)) == 42 with pytest.raises(TypeError) as excinfo: m.refwrap_builtin(None) assert "incompatible function arguments" in str(excinfo.value) with pytest.raises(TypeError) as excinfo: m.refwrap_usertype(None) assert "incompatible function arguments" in str(excinfo.value) assert m.refwrap_lvalue().value == 1 assert m.refwrap_lvalue_const().value == 1 a1 = m.refwrap_list(copy=True) a2 = m.refwrap_list(copy=True) assert [x.value for x in a1] == [2, 3] assert [x.value for x in a2] == [2, 3] assert a1[0] is not a2[0] assert a1[1] is not a2[1] b1 = m.refwrap_list(copy=False) b2 = m.refwrap_list(copy=False) assert [x.value for x in b1] == [1, 2] assert [x.value for x in b2] == [1, 2] assert b1[0] is b2[0] assert b1[1] is b2[1] assert m.refwrap_iiw(IncType(5)) == 5 assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10] def test_complex_cast(doc): """std::complex casts""" class Complex: def __complex__(self) -> complex: return complex(5, 4) class Float: def __float__(self) -> float: return 5.0 class Int: def __int__(self) -> int: return 3 class Index: def __index__(self) -> int: return 1 assert m.complex_cast(1) == "1.0" assert m.complex_cast(1.0) == "1.0" assert m.complex_cast(Complex()) == "(5.0, 4.0)" assert m.complex_cast(2j) == "(0.0, 2.0)" assert m.complex_cast_strict(1) == "(1.0, 0.0)" assert m.complex_cast_strict(3.0) == "(3.0, 0.0)" assert m.complex_cast_strict(complex(5, 4)) == "(5.0, 4.0)" assert m.complex_cast_strict(2j) == "(0.0, 2.0)" convert, noconvert = m.complex_convert, m.complex_noconvert def requires_conversion(v): pytest.raises(TypeError, noconvert, v) def cant_convert(v): pytest.raises(TypeError, convert, v) assert ( doc(convert) == "complex_convert(arg0: typing.SupportsComplex | typing.SupportsFloat | typing.SupportsIndex) -> complex" ) assert doc(noconvert) == "complex_noconvert(arg0: complex) -> complex" assert convert(1) == 1.0 assert convert(2.0) == 2.0 assert convert(1 + 5j) == 1.0 + 5.0j assert convert(Complex()) == 5.0 + 4j assert convert(Float()) == 5.0 assert isinstance(convert(Float()), complex) cant_convert(Int()) assert convert(Index()) == 1 assert isinstance(convert(Index()), complex) assert noconvert(1) == 1.0 assert noconvert(2.0) == 2.0 assert noconvert(1 + 5j) == 1.0 + 5.0j requires_conversion(Complex()) requires_conversion(Float()) requires_conversion(Index()) def test_complex_index_handling(): """ Test __index__ handling in complex caster (added with PR #5879). This test verifies that custom __index__ objects (not PyLong) work correctly with complex conversion. The behavior should be consistent across CPython, PyPy, and GraalPy. - Custom __index__ objects work with convert (non-strict mode) - Custom __index__ objects do NOT work with noconvert (strict mode) - Regular int (PyLong) works with both convert and noconvert """ class CustomIndex: """Custom class with __index__ but not __int__ or __float__""" def __index__(self) -> int: return 42 class CustomIndexNegative: """Custom class with negative __index__""" def __index__(self) -> int: return -17 convert, noconvert = m.complex_convert, m.complex_noconvert # Test that regular int (PyLong) works assert convert(5) == 5.0 + 0j assert noconvert(5) == 5.0 + 0j # Test that custom __index__ objects work with convert (non-strict mode) # This exercises the PyPy-specific path in complex.h assert convert(CustomIndex()) == 42.0 + 0j assert convert(CustomIndexNegative()) == -17.0 + 0j # With noconvert (strict mode), custom __index__ objects are NOT accepted # Strict mode only accepts complex, float, or int (PyLong), not custom __index__ objects def requires_conversion(v): pytest.raises(TypeError, noconvert, v) requires_conversion(CustomIndex()) requires_conversion(CustomIndexNegative()) # Verify the result is actually a complex result = convert(CustomIndex()) assert isinstance(result, complex) assert result.real == 42.0 assert result.imag == 0.0 def test_overload_resolution_float_int(): """ Test overload resolution behavior when int can match float (added with PR #5879). This test documents the breaking change in PR #5879: when a float overload is registered before an int overload, passing a Python int will now match the float overload (because int can be converted to float in strict mode per PEP 484). Before PR #5879: int(42) would match int overload (if both existed) After PR #5879: int(42) matches float overload (if registered first) This is a breaking change because existing code that relied on int matching int overloads may now match float overloads instead. """ # Test 1: float overload registered first, int second # When passing int(42), pybind11 tries overloads in order: # 1. float overload - can int(42) be converted? Yes (with PR #5879 changes) # 2. Match! Use float overload (int overload never checked) result = m.overload_resolution_test(42) assert result == "float: 42.000000", ( f"Expected int(42) to match float overload, got: {result}. " "This documents the breaking change: int now matches float overloads." ) assert m.overload_resolution_test(42.0) == "float: 42.000000" # Test 2: With noconvert (strict mode) - this is the KEY breaking change # Before PR #5879: int(42) would NOT match float overload with noconvert, would match int overload # After PR #5879: int(42) DOES match float overload with noconvert (because int->float is now allowed) result_strict = m.overload_resolution_strict(42) assert result_strict == "float_strict: 42.000000", ( f"Expected int(42) to match float overload with noconvert, got: {result_strict}. " "This is the key breaking change: int now matches float even in strict mode." ) assert m.overload_resolution_strict(42.0) == "float_strict: 42.000000" # Test 3: complex overload registered first, then float, then int # When passing int(5), pybind11 tries overloads in order: # 1. complex overload - can int(5) be converted? Yes (with PR #5879 changes) # 2. Match! Use complex overload assert m.overload_resolution_complex(5) == "complex: (5.000000, 0.000000)" assert m.overload_resolution_complex(5.0) == "complex: (5.000000, 0.000000)" assert ( m.overload_resolution_complex(complex(3, 4)) == "complex: (3.000000, 4.000000)" ) # Verify that the overloads are registered in the expected order # The docstring should show float overload before int overload doc = m.overload_resolution_test.__doc__ assert doc is not None # Check that float overload appears before int overload in docstring # The docstring uses "typing.SupportsFloat" and "typing.SupportsInt" float_pos = doc.find("SupportsFloat") int_pos = doc.find("SupportsInt") assert float_pos != -1, f"Could not find 'SupportsFloat' in docstring: {doc}" assert int_pos != -1, f"Could not find 'SupportsInt' in docstring: {doc}" assert float_pos < int_pos, ( f"Float overload should appear before int overload in docstring. " f"Found 'SupportsFloat' at {float_pos}, 'SupportsInt' at {int_pos}. " f"Docstring: {doc}" ) def test_bool_caster(): """Test bool caster implicit conversions.""" convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert def require_implicit(v): pytest.raises(TypeError, noconvert, v) def cant_convert(v): pytest.raises(TypeError, convert, v) # straight up bool assert convert(True) is True assert convert(False) is False assert noconvert(True) is True assert noconvert(False) is False # None requires implicit conversion require_implicit(None) assert convert(None) is False class A: def __init__(self, x): self.x = x def __nonzero__(self): return self.x def __bool__(self): return self.x class B: pass # Arbitrary objects are not accepted cant_convert(object()) cant_convert(B()) # Objects with __nonzero__ / __bool__ defined can be converted require_implicit(A(True)) assert convert(A(True)) is True assert convert(A(False)) is False def test_numpy_bool(): np = pytest.importorskip("numpy") convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert def cant_convert(v): pytest.raises(TypeError, convert, v) # np.bool_ is not considered implicit assert convert(np.bool_(True)) is True assert convert(np.bool_(False)) is False assert noconvert(np.bool_(True)) is True assert noconvert(np.bool_(False)) is False cant_convert(np.zeros(2, dtype="int")) def test_int_long(): assert isinstance(m.int_cast(), int) assert isinstance(m.long_cast(), int) assert isinstance(m.longlong_cast(), int) def test_void_caster_2(): assert m.test_void_caster() def test_const_ref_caster(): """Verifies that const-ref is propagated through type_caster cast_op. The returned ConstRefCasted type is a minimal type that is constructed to reference the casting mode used. """ x = False assert m.takes(x) == 1 assert m.takes_move(x) == 1 assert m.takes_ptr(x) == 3 assert m.takes_ref(x) == 2 assert m.takes_ref_wrap(x) == 2 assert m.takes_const_ptr(x) == 5 assert m.takes_const_ref(x) == 4 assert m.takes_const_ref_wrap(x) == 4