Blame external/pybind11/tests/test_builtin_casters.py

Packit 534379
# Python < 3 needs this: coding=utf-8
Packit 534379
import pytest
Packit 534379
Packit 534379
from pybind11_tests import builtin_casters as m
Packit 534379
from pybind11_tests import UserType, IncType
Packit 534379
Packit 534379
Packit 534379
def test_simple_string():
Packit 534379
    assert m.string_roundtrip("const char *") == "const char *"
Packit 534379
Packit 534379
Packit 534379
def test_unicode_conversion():
Packit 534379
    """Tests unicode conversion and error reporting."""
Packit 534379
    assert m.good_utf8_string() == u"Say utf8β€½ πŸŽ‚ 𝐀"
Packit 534379
    assert m.good_utf16_string() == u"bβ€½πŸŽ‚π€z"
Packit 534379
    assert m.good_utf32_string() == u"aπ€πŸŽ‚β€½z"
Packit 534379
    assert m.good_wchar_string() == u"aβΈ˜π€z"
Packit 534379
Packit 534379
    with pytest.raises(UnicodeDecodeError):
Packit 534379
        m.bad_utf8_string()
Packit 534379
Packit 534379
    with pytest.raises(UnicodeDecodeError):
Packit 534379
        m.bad_utf16_string()
Packit 534379
Packit 534379
    # These are provided only if they actually fail (they don't when 32-bit and under Python 2.7)
Packit 534379
    if hasattr(m, "bad_utf32_string"):
Packit 534379
        with pytest.raises(UnicodeDecodeError):
Packit 534379
            m.bad_utf32_string()
Packit 534379
    if hasattr(m, "bad_wchar_string"):
Packit 534379
        with pytest.raises(UnicodeDecodeError):
Packit 534379
            m.bad_wchar_string()
Packit 534379
Packit 534379
    assert m.u8_Z() == 'Z'
Packit 534379
    assert m.u8_eacute() == u'Γ©'
Packit 534379
    assert m.u16_ibang() == u'β€½'
Packit 534379
    assert m.u32_mathbfA() == u'𝐀'
Packit 534379
    assert m.wchar_heart() == u'β™₯'
Packit 534379
Packit 534379
Packit 534379
def test_single_char_arguments():
Packit 534379
    """Tests failures for passing invalid inputs to char-accepting functions"""
Packit 534379
    def toobig_message(r):
Packit 534379
        return "Character code point not in range({0:#x})".format(r)
Packit 534379
    toolong_message = "Expected a character, but multi-character string found"
Packit 534379
Packit 534379
    assert m.ord_char(u'a') == 0x61  # simple ASCII
Packit 534379
    assert m.ord_char_lv(u'b') == 0x62
Packit 534379
    assert m.ord_char(u'Γ©') == 0xE9  # requires 2 bytes in utf-8, but can be stuffed in a char
Packit 534379
    with pytest.raises(ValueError) as excinfo:
Packit 534379
        assert m.ord_char(u'Δ€') == 0x100  # requires 2 bytes, doesn't fit in a char
Packit 534379
    assert str(excinfo.value) == toobig_message(0x100)
Packit 534379
    with pytest.raises(ValueError) as excinfo:
Packit 534379
        assert m.ord_char(u'ab')
Packit 534379
    assert str(excinfo.value) == toolong_message
Packit 534379
Packit 534379
    assert m.ord_char16(u'a') == 0x61
Packit 534379
    assert m.ord_char16(u'Γ©') == 0xE9
Packit 534379
    assert m.ord_char16_lv(u'Γͺ') == 0xEA
Packit 534379
    assert m.ord_char16(u'Δ€') == 0x100
Packit 534379
    assert m.ord_char16(u'β€½') == 0x203d
Packit 534379
    assert m.ord_char16(u'β™₯') == 0x2665
Packit 534379
    assert m.ord_char16_lv(u'β™‘') == 0x2661
Packit 534379
    with pytest.raises(ValueError) as excinfo:
Packit 534379
        assert m.ord_char16(u'πŸŽ‚') == 0x1F382  # requires surrogate pair
Packit 534379
    assert str(excinfo.value) == toobig_message(0x10000)
Packit 534379
    with pytest.raises(ValueError) as excinfo:
Packit 534379
        assert m.ord_char16(u'aa')
Packit 534379
    assert str(excinfo.value) == toolong_message
Packit 534379
Packit 534379
    assert m.ord_char32(u'a') == 0x61
Packit 534379
    assert m.ord_char32(u'Γ©') == 0xE9
Packit 534379
    assert m.ord_char32(u'Δ€') == 0x100
Packit 534379
    assert m.ord_char32(u'β€½') == 0x203d
Packit 534379
    assert m.ord_char32(u'β™₯') == 0x2665
Packit 534379
    assert m.ord_char32(u'πŸŽ‚') == 0x1F382
Packit 534379
    with pytest.raises(ValueError) as excinfo:
Packit 534379
        assert m.ord_char32(u'aa')
Packit 534379
    assert str(excinfo.value) == toolong_message
Packit 534379
Packit 534379
    assert m.ord_wchar(u'a') == 0x61
Packit 534379
    assert m.ord_wchar(u'Γ©') == 0xE9
Packit 534379
    assert m.ord_wchar(u'Δ€') == 0x100
Packit 534379
    assert m.ord_wchar(u'β€½') == 0x203d
Packit 534379
    assert m.ord_wchar(u'β™₯') == 0x2665
Packit 534379
    if m.wchar_size == 2:
Packit 534379
        with pytest.raises(ValueError) as excinfo:
Packit 534379
            assert m.ord_wchar(u'πŸŽ‚') == 0x1F382  # requires surrogate pair
Packit 534379
        assert str(excinfo.value) == toobig_message(0x10000)
Packit 534379
    else:
Packit 534379
        assert m.ord_wchar(u'πŸŽ‚') == 0x1F382
Packit 534379
    with pytest.raises(ValueError) as excinfo:
Packit 534379
        assert m.ord_wchar(u'aa')
Packit 534379
    assert str(excinfo.value) == toolong_message
Packit 534379
Packit 534379
Packit 534379
def test_bytes_to_string():
Packit 534379
    """Tests the ability to pass bytes to C++ string-accepting functions.  Note that this is
Packit 534379
    one-way: the only way to return bytes to Python is via the pybind11::bytes class."""
Packit 534379
    # Issue #816
Packit 534379
    import sys
Packit 534379
    byte = bytes if sys.version_info[0] < 3 else str
Packit 534379
Packit 534379
    assert m.strlen(byte("hi")) == 2
Packit 534379
    assert m.string_length(byte("world")) == 5
Packit 534379
    assert m.string_length(byte("a\x00b")) == 3
Packit 534379
    assert m.strlen(byte("a\x00b")) == 1  # C-string limitation
Packit 534379
Packit 534379
    # passing in a utf8 encoded string should work
Packit 534379
    assert m.string_length(u'πŸ’©'.encode("utf8")) == 4
Packit 534379
Packit 534379
Packit 534379
@pytest.mark.skipif(not hasattr(m, "has_string_view"), reason="no <string_view>")
Packit 534379
def test_string_view(capture):
Packit 534379
    """Tests support for C++17 string_view arguments and return values"""
Packit 534379
    assert m.string_view_chars("Hi") == [72, 105]
Packit 534379
    assert m.string_view_chars("Hi πŸŽ‚") == [72, 105, 32, 0xf0, 0x9f, 0x8e, 0x82]
Packit 534379
    assert m.string_view16_chars("Hi πŸŽ‚") == [72, 105, 32, 0xd83c, 0xdf82]
Packit 534379
    assert m.string_view32_chars("Hi πŸŽ‚") == [72, 105, 32, 127874]
Packit 534379
Packit 534379
    assert m.string_view_return() == "utf8 secret πŸŽ‚"
Packit 534379
    assert m.string_view16_return() == "utf16 secret πŸŽ‚"
Packit 534379
    assert m.string_view32_return() == "utf32 secret πŸŽ‚"
Packit 534379
Packit 534379
    with capture:
Packit 534379
        m.string_view_print("Hi")
Packit 534379
        m.string_view_print("utf8 πŸŽ‚")
Packit 534379
        m.string_view16_print("utf16 πŸŽ‚")
Packit 534379
        m.string_view32_print("utf32 πŸŽ‚")
Packit 534379
    assert capture == """
Packit 534379
        Hi 2
Packit 534379
        utf8 πŸŽ‚ 9
Packit 534379
        utf16 πŸŽ‚ 8
Packit 534379
        utf32 πŸŽ‚ 7
Packit 534379
    """
Packit 534379
Packit 534379
    with capture:
Packit 534379
        m.string_view_print("Hi, ascii")
Packit 534379
        m.string_view_print("Hi, utf8 πŸŽ‚")
Packit 534379
        m.string_view16_print("Hi, utf16 πŸŽ‚")
Packit 534379
        m.string_view32_print("Hi, utf32 πŸŽ‚")
Packit 534379
    assert capture == """
Packit 534379
        Hi, ascii 9
Packit 534379
        Hi, utf8 πŸŽ‚ 13
Packit 534379
        Hi, utf16 πŸŽ‚ 12
Packit 534379
        Hi, utf32 πŸŽ‚ 11
Packit 534379
    """
Packit 534379
Packit 534379
Packit 534379
def test_integer_casting():
Packit 534379
    """Issue #929 - out-of-range integer values shouldn't be accepted"""
Packit 534379
    import sys
Packit 534379
    assert m.i32_str(-1) == "-1"
Packit 534379
    assert m.i64_str(-1) == "-1"
Packit 534379
    assert m.i32_str(2000000000) == "2000000000"
Packit 534379
    assert m.u32_str(2000000000) == "2000000000"
Packit 534379
    if sys.version_info < (3,):
Packit 534379
        assert m.i32_str(long(-1)) == "-1"  # noqa: F821 undefined name 'long'
Packit 534379
        assert m.i64_str(long(-1)) == "-1"  # noqa: F821 undefined name 'long'
Packit 534379
        assert m.i64_str(long(-999999999999)) == "-999999999999"  # noqa: F821 undefined name
Packit 534379
        assert m.u64_str(long(999999999999)) == "999999999999"  # noqa: F821 undefined name 'long'
Packit 534379
    else:
Packit 534379
        assert m.i64_str(-999999999999) == "-999999999999"
Packit 534379
        assert m.u64_str(999999999999) == "999999999999"
Packit 534379
Packit 534379
    with pytest.raises(TypeError) as excinfo:
Packit 534379
        m.u32_str(-1)
Packit 534379
    assert "incompatible function arguments" in str(excinfo.value)
Packit 534379
    with pytest.raises(TypeError) as excinfo:
Packit 534379
        m.u64_str(-1)
Packit 534379
    assert "incompatible function arguments" in str(excinfo.value)
Packit 534379
    with pytest.raises(TypeError) as excinfo:
Packit 534379
        m.i32_str(-3000000000)
Packit 534379
    assert "incompatible function arguments" in str(excinfo.value)
Packit 534379
    with pytest.raises(TypeError) as excinfo:
Packit 534379
        m.i32_str(3000000000)
Packit 534379
    assert "incompatible function arguments" in str(excinfo.value)
Packit 534379
Packit 534379
    if sys.version_info < (3,):
Packit 534379
        with pytest.raises(TypeError) as excinfo:
Packit 534379
            m.u32_str(long(-1))  # noqa: F821 undefined name 'long'
Packit 534379
        assert "incompatible function arguments" in str(excinfo.value)
Packit 534379
        with pytest.raises(TypeError) as excinfo:
Packit 534379
            m.u64_str(long(-1))  # noqa: F821 undefined name 'long'
Packit 534379
        assert "incompatible function arguments" in str(excinfo.value)
Packit 534379
Packit 534379
Packit 534379
def test_tuple(doc):
Packit 534379
    """std::pair <-> tuple & std::tuple <-> tuple"""
Packit 534379
    assert m.pair_passthrough((True, "test")) == ("test", True)
Packit 534379
    assert m.tuple_passthrough((True, "test", 5)) == (5, "test", True)
Packit 534379
    # Any sequence can be cast to a std::pair or std::tuple
Packit 534379
    assert m.pair_passthrough([True, "test"]) == ("test", True)
Packit 534379
    assert m.tuple_passthrough([True, "test", 5]) == (5, "test", True)
Packit 534379
    assert m.empty_tuple() == ()
Packit 534379
Packit 534379
    assert doc(m.pair_passthrough) == """
Packit 534379
        pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]
Packit 534379
Packit 534379
        Return a pair in reversed order
Packit 534379
    """
Packit 534379
    assert doc(m.tuple_passthrough) == """
Packit 534379
        tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]
Packit 534379
Packit 534379
        Return a triple in reversed order
Packit 534379
    """
Packit 534379
Packit 534379
    assert m.rvalue_pair() == ("rvalue", "rvalue")
Packit 534379
    assert m.lvalue_pair() == ("lvalue", "lvalue")
Packit 534379
    assert m.rvalue_tuple() == ("rvalue", "rvalue", "rvalue")
Packit 534379
    assert m.lvalue_tuple() == ("lvalue", "lvalue", "lvalue")
Packit 534379
    assert m.rvalue_nested() == ("rvalue", ("rvalue", ("rvalue", "rvalue")))
Packit 534379
    assert m.lvalue_nested() == ("lvalue", ("lvalue", ("lvalue", "lvalue")))
Packit 534379
Packit 534379
Packit 534379
def test_builtins_cast_return_none():
Packit 534379
    """Casters produced with PYBIND11_TYPE_CASTER() should convert nullptr to None"""
Packit 534379
    assert m.return_none_string() is None
Packit 534379
    assert m.return_none_char() is None
Packit 534379
    assert m.return_none_bool() is None
Packit 534379
    assert m.return_none_int() is None
Packit 534379
    assert m.return_none_float() is None
Packit 534379
Packit 534379
Packit 534379
def test_none_deferred():
Packit 534379
    """None passed as various argument types should defer to other overloads"""
Packit 534379
    assert not m.defer_none_cstring("abc")
Packit 534379
    assert m.defer_none_cstring(None)
Packit 534379
    assert not m.defer_none_custom(UserType())
Packit 534379
    assert m.defer_none_custom(None)
Packit 534379
    assert m.nodefer_none_void(None)
Packit 534379
Packit 534379
Packit 534379
def test_void_caster():
Packit 534379
    assert m.load_nullptr_t(None) is None
Packit 534379
    assert m.cast_nullptr_t() is None
Packit 534379
Packit 534379
Packit 534379
def test_reference_wrapper():
Packit 534379
    """std::reference_wrapper for builtin and user types"""
Packit 534379
    assert m.refwrap_builtin(42) == 420
Packit 534379
    assert m.refwrap_usertype(UserType(42)) == 42
Packit 534379
Packit 534379
    with pytest.raises(TypeError) as excinfo:
Packit 534379
        m.refwrap_builtin(None)
Packit 534379
    assert "incompatible function arguments" in str(excinfo.value)
Packit 534379
Packit 534379
    with pytest.raises(TypeError) as excinfo:
Packit 534379
        m.refwrap_usertype(None)
Packit 534379
    assert "incompatible function arguments" in str(excinfo.value)
Packit 534379
Packit 534379
    a1 = m.refwrap_list(copy=True)
Packit 534379
    a2 = m.refwrap_list(copy=True)
Packit 534379
    assert [x.value for x in a1] == [2, 3]
Packit 534379
    assert [x.value for x in a2] == [2, 3]
Packit 534379
    assert not a1[0] is a2[0] and not a1[1] is a2[1]
Packit 534379
Packit 534379
    b1 = m.refwrap_list(copy=False)
Packit 534379
    b2 = m.refwrap_list(copy=False)
Packit 534379
    assert [x.value for x in b1] == [1, 2]
Packit 534379
    assert [x.value for x in b2] == [1, 2]
Packit 534379
    assert b1[0] is b2[0] and b1[1] is b2[1]
Packit 534379
Packit 534379
    assert m.refwrap_iiw(IncType(5)) == 5
Packit 534379
    assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]
Packit 534379
Packit 534379
Packit 534379
def test_complex_cast():
Packit 534379
    """std::complex casts"""
Packit 534379
    assert m.complex_cast(1) == "1.0"
Packit 534379
    assert m.complex_cast(2j) == "(0.0, 2.0)"
Packit 534379
Packit 534379
Packit 534379
def test_bool_caster():
Packit 534379
    """Test bool caster implicit conversions."""
Packit 534379
    convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
Packit 534379
Packit 534379
    def require_implicit(v):
Packit 534379
        pytest.raises(TypeError, noconvert, v)
Packit 534379
Packit 534379
    def cant_convert(v):
Packit 534379
        pytest.raises(TypeError, convert, v)
Packit 534379
Packit 534379
    # straight up bool
Packit 534379
    assert convert(True) is True
Packit 534379
    assert convert(False) is False
Packit 534379
    assert noconvert(True) is True
Packit 534379
    assert noconvert(False) is False
Packit 534379
Packit 534379
    # None requires implicit conversion
Packit 534379
    require_implicit(None)
Packit 534379
    assert convert(None) is False
Packit 534379
Packit 534379
    class A(object):
Packit 534379
        def __init__(self, x):
Packit 534379
            self.x = x
Packit 534379
Packit 534379
        def __nonzero__(self):
Packit 534379
            return self.x
Packit 534379
Packit 534379
        def __bool__(self):
Packit 534379
            return self.x
Packit 534379
Packit 534379
    class B(object):
Packit 534379
        pass
Packit 534379
Packit 534379
    # Arbitrary objects are not accepted
Packit 534379
    cant_convert(object())
Packit 534379
    cant_convert(B())
Packit 534379
Packit 534379
    # Objects with __nonzero__ / __bool__ defined can be converted
Packit 534379
    require_implicit(A(True))
Packit 534379
    assert convert(A(True)) is True
Packit 534379
    assert convert(A(False)) is False
Packit 534379
Packit 534379
Packit 534379
@pytest.requires_numpy
Packit 534379
def test_numpy_bool():
Packit 534379
    import numpy as np
Packit 534379
    convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
Packit 534379
Packit 534379
    # np.bool_ is not considered implicit
Packit 534379
    assert convert(np.bool_(True)) is True
Packit 534379
    assert convert(np.bool_(False)) is False
Packit 534379
    assert noconvert(np.bool_(True)) is True
Packit 534379
    assert noconvert(np.bool_(False)) is False
Packit 534379
Packit 534379
Packit 534379
def test_int_long():
Packit 534379
    """In Python 2, a C++ int should return a Python int rather than long
Packit 534379
    if possible: longs are not always accepted where ints are used (such
Packit 534379
    as the argument to sys.exit()). A C++ long long is always a Python
Packit 534379
    long."""
Packit 534379
Packit 534379
    import sys
Packit 534379
    must_be_long = type(getattr(sys, 'maxint', 1) + 1)
Packit 534379
    assert isinstance(m.int_cast(), int)
Packit 534379
    assert isinstance(m.long_cast(), int)
Packit 534379
    assert isinstance(m.longlong_cast(), must_be_long)
Packit 534379
Packit 534379
Packit 534379
def test_void_caster_2():
Packit 534379
    assert m.test_void_caster()