def test_pointers(msg):
    from pybind11_tests import (return_void_ptr, get_void_ptr_value, ExampleMandA,
                                print_opaque_list, return_null_str, get_null_str_value,
                                return_unique_ptr, ConstructorStats)

    living_before = ConstructorStats.get(ExampleMandA).alive()
    assert get_void_ptr_value(return_void_ptr()) == 0x1234
    assert get_void_ptr_value(ExampleMandA())  # Should also work for other C++ types
    assert ConstructorStats.get(ExampleMandA).alive() == living_before

    with pytest.raises(TypeError) as excinfo:
        get_void_ptr_value([1, 2, 3])  # This should not work
    assert msg(excinfo.value) == """
        get_void_ptr_value(): incompatible function arguments. The following argument types are supported:
            1. (arg0: capsule) -> int

        Invoked with: [1, 2, 3]
    """  # noqa: E501 line too long

    assert return_null_str() is None
    assert get_null_str_value(return_null_str()) is not None

    ptr = return_unique_ptr()
    assert "StringList" in repr(ptr)
    assert print_opaque_list(ptr) == "Opaque list: [some value]"
Exemple #2
0
def test_reference_internal():
    from pybind11_tests import ConstructorStats
    from pybind11_tests.submodule import A, B

    b = B()
    assert str(b.get_a1()) == "A[1]"
    assert str(b.a1) == "A[1]"
    assert str(b.get_a2()) == "A[2]"
    assert str(b.a2) == "A[2]"

    b.a1 = A(42)
    b.a2 = A(43)
    assert str(b.get_a1()) == "A[42]"
    assert str(b.a1) == "A[42]"
    assert str(b.get_a2()) == "A[43]"
    assert str(b.a2) == "A[43]"

    astats, bstats = ConstructorStats.get(A), ConstructorStats.get(B)
    assert astats.alive() == 2
    assert bstats.alive() == 1
    del b
    assert astats.alive() == 0
    assert bstats.alive() == 0
    assert astats.values() == ['1', '2', '42', '43']
    assert bstats.values() == []
    assert astats.default_constructions == 0
    assert bstats.default_constructions == 1
    assert astats.copy_constructions == 0
    assert bstats.copy_constructions == 0
    # assert astats.move_constructions >= 0  # Don't invoke any
    # assert bstats.move_constructions >= 0  # Don't invoke any
    assert astats.copy_assignments == 2
    assert bstats.copy_assignments == 0
    assert astats.move_assignments == 0
    assert bstats.move_assignments == 0
def test_unique_nodelete():
    from pybind11_tests import MyObject4
    o = MyObject4(23)
    assert o.value == 23
    cstats = ConstructorStats.get(MyObject4)
    assert cstats.alive() == 1
    del o
    cstats = ConstructorStats.get(MyObject4)
    assert cstats.alive() == 1  # Leak, but that's intentional
Exemple #4
0
def test_unique_nodelete():
    o = m.MyObject4(23)
    assert o.value == 23
    cstats = ConstructorStats.get(m.MyObject4)
    assert cstats.alive() == 1
    del o
    assert cstats.alive() == 1  # Leak, but that's intentional
Exemple #5
0
def test_holder_with_addressof_operator():
    # this test must not throw exception from c++
    a = m.TypeForHolderWithAddressOf.make()
    a.print_object_1()
    a.print_object_2()
    a.print_object_3()
    a.print_object_4()

    stats = ConstructorStats.get(m.TypeForHolderWithAddressOf)
    assert stats.alive() == 1

    np = m.TypeForHolderWithAddressOf.make()
    assert stats.alive() == 2
    del a
    assert stats.alive() == 1
    del np
    assert stats.alive() == 0

    b = m.TypeForHolderWithAddressOf.make()
    c = b
    assert b.get() is c.get()
    assert stats.alive() == 1

    del b
    assert stats.alive() == 1

    del c
    assert stats.alive() == 0
Exemple #6
0
def test_to_python():
    mat = m.Matrix(5, 5)
    assert memoryview(mat).shape == (5, 5)

    assert mat[2, 3] == 0
    mat[2, 3] = 4
    assert mat[2, 3] == 4

    mat2 = np.array(mat, copy=False)
    assert mat2.shape == (5, 5)
    assert abs(mat2).sum() == 4
    assert mat2[2, 3] == 4
    mat2[2, 3] = 5
    assert mat2[2, 3] == 5

    cstats = ConstructorStats.get(m.Matrix)
    assert cstats.alive() == 1
    del mat
    pytest.gc_collect()
    assert cstats.alive() == 1
    del mat2  # holds a mat reference
    pytest.gc_collect()
    assert cstats.alive() == 0
    assert cstats.values() == ["5x5 matrix"]
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0  # Don't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
Exemple #7
0
def test_stl_ownership():
    cstats = ConstructorStats.get(m.Placeholder)
    assert cstats.alive() == 0
    r = m.test_stl_ownership()
    assert len(r) == 1
    del r
    assert cstats.alive() == 0
Exemple #8
0
def test_to_python():
    m = Matrix(5, 5)

    assert m[2, 3] == 0
    m[2, 3] = 4
    assert m[2, 3] == 4

    m2 = np.array(m, copy=False)
    assert m2.shape == (5, 5)
    assert abs(m2).sum() == 4
    assert m2[2, 3] == 4
    m2[2, 3] = 5
    assert m2[2, 3] == 5

    cstats = ConstructorStats.get(Matrix)
    assert cstats.alive() == 1
    del m
    pytest.gc_collect()
    assert cstats.alive() == 1
    del m2  # holds an m reference
    pytest.gc_collect()
    assert cstats.alive() == 0
    assert cstats.values() == ["5x5 matrix"]
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0  # Don't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
def test_shared_ptr_and_references():
    from pybind11_tests.smart_ptr import SharedPtrRef, A

    s = SharedPtrRef()
    stats = ConstructorStats.get(A)
    assert stats.alive() == 2

    ref = s.ref  # init_holder_helper(holder_ptr=false, owned=false)
    assert stats.alive() == 2
    assert s.set_ref(ref)
    with pytest.raises(RuntimeError) as excinfo:
        assert s.set_holder(ref)
    assert "Unable to cast from non-held to held instance" in str(excinfo.value)

    copy = s.copy  # init_holder_helper(holder_ptr=false, owned=true)
    assert stats.alive() == 3
    assert s.set_ref(copy)
    assert s.set_holder(copy)

    holder_ref = s.holder_ref  # init_holder_helper(holder_ptr=true, owned=false)
    assert stats.alive() == 3
    assert s.set_ref(holder_ref)
    assert s.set_holder(holder_ref)

    holder_copy = s.holder_copy  # init_holder_helper(holder_ptr=true, owned=true)
    assert stats.alive() == 3
    assert s.set_ref(holder_copy)
    assert s.set_holder(holder_copy)

    del ref, copy, holder_ref, holder_copy, s
    assert stats.alive() == 0
Exemple #10
0
def test_large_holder():
    o = m.MyObject5(5)
    assert o.value == 5
    cstats = ConstructorStats.get(m.MyObject5)
    assert cstats.alive() == 1
    del o
    assert cstats.alive() == 0
def test_methods_and_attributes():
    instance1 = m.ExampleMandA()
    instance2 = m.ExampleMandA(32)

    instance1.add1(instance2)
    instance1.add2(instance2)
    instance1.add3(instance2)
    instance1.add4(instance2)
    instance1.add5(instance2)
    instance1.add6(32)
    instance1.add7(32)
    instance1.add8(32)
    instance1.add9(32)
    instance1.add10(32)

    assert str(instance1) == "ExampleMandA[value=320]"
    assert str(instance2) == "ExampleMandA[value=32]"
    assert str(instance1.self1()) == "ExampleMandA[value=320]"
    assert str(instance1.self2()) == "ExampleMandA[value=320]"
    assert str(instance1.self3()) == "ExampleMandA[value=320]"
    assert str(instance1.self4()) == "ExampleMandA[value=320]"
    assert str(instance1.self5()) == "ExampleMandA[value=320]"

    assert instance1.internal1() == 320
    assert instance1.internal2() == 320
    assert instance1.internal3() == 320
    assert instance1.internal4() == 320
    assert instance1.internal5() == 320

    assert instance1.overloaded() == "()"
    assert instance1.overloaded(0) == "(int)"
    assert instance1.overloaded(1, 1.0) == "(int, float)"
    assert instance1.overloaded(2.0, 2) == "(float, int)"
    assert instance1.overloaded(3,   3) == "(int, int)"
    assert instance1.overloaded(4., 4.) == "(float, float)"
    assert instance1.overloaded_const(-3) == "(int) const"
    assert instance1.overloaded_const(5, 5.0) == "(int, float) const"
    assert instance1.overloaded_const(6.0, 6) == "(float, int) const"
    assert instance1.overloaded_const(7,   7) == "(int, int) const"
    assert instance1.overloaded_const(8., 8.) == "(float, float) const"
    assert instance1.overloaded_float(1, 1) == "(float, float)"
    assert instance1.overloaded_float(1, 1.) == "(float, float)"
    assert instance1.overloaded_float(1., 1) == "(float, float)"
    assert instance1.overloaded_float(1., 1.) == "(float, float)"

    assert instance1.value == 320
    instance1.value = 100
    assert str(instance1) == "ExampleMandA[value=100]"

    cstats = ConstructorStats.get(m.ExampleMandA)
    assert cstats.alive() == 2
    del instance1, instance2
    assert cstats.alive() == 0
    assert cstats.values() == ["32"]
    assert cstats.default_constructions == 1
    assert cstats.copy_constructions == 3
    assert cstats.move_constructions >= 1
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
Exemple #12
0
def test_large_holder():
    from pybind11_tests import MyObject5
    o = MyObject5(5)
    assert o.value == 5
    cstats = ConstructorStats.get(MyObject5)
    assert cstats.alive() == 1
    del o
    assert cstats.alive() == 0
def test_move_only_holder():
    from pybind11_tests.smart_ptr import TypeWithMoveOnlyHolder

    a = TypeWithMoveOnlyHolder.make()
    stats = ConstructorStats.get(TypeWithMoveOnlyHolder)
    assert stats.alive() == 1
    del a
    assert stats.alive() == 0
def test_move_support():
    from pybind11_tests import NCVirt, NonCopyable, Movable

    class NCVirtExt(NCVirt):
        def get_noncopyable(self, a, b):
            # Constructs and returns a new instance:
            nc = NonCopyable(a * a, b * b)
            return nc

        def get_movable(self, a, b):
            # Return a referenced copy
            self.movable = Movable(a, b)
            return self.movable

    class NCVirtExt2(NCVirt):
        def get_noncopyable(self, a, b):
            # Keep a reference: this is going to throw an exception
            self.nc = NonCopyable(a, b)
            return self.nc

        def get_movable(self, a, b):
            # Return a new instance without storing it
            return Movable(a, b)

    ncv1 = NCVirtExt()
    assert ncv1.print_nc(2, 3) == "36"
    assert ncv1.print_movable(4, 5) == "9"
    ncv2 = NCVirtExt2()
    assert ncv2.print_movable(7, 7) == "14"
    # Don't check the exception message here because it differs under debug/non-debug mode
    with pytest.raises(RuntimeError):
        ncv2.print_nc(9, 9)

    nc_stats = ConstructorStats.get(NonCopyable)
    mv_stats = ConstructorStats.get(Movable)
    assert nc_stats.alive() == 1
    assert mv_stats.alive() == 1
    del ncv1, ncv2
    assert nc_stats.alive() == 0
    assert mv_stats.alive() == 0
    assert nc_stats.values() == ['4', '9', '9', '9']
    assert mv_stats.values() == ['4', '5', '7', '7']
    assert nc_stats.copy_constructions == 0
    assert mv_stats.copy_constructions == 1
    assert nc_stats.move_constructions >= 0
    assert mv_stats.move_constructions >= 0
def test_sequence():
    from pybind11_tests import ConstructorStats
    from pybind11_tests.sequences_and_iterators import Sequence

    cstats = ConstructorStats.get(Sequence)

    s = Sequence(5)
    assert cstats.values() == ['of size', '5']

    assert "Sequence" in repr(s)
    assert len(s) == 5
    assert s[0] == 0 and s[3] == 0
    assert 12.34 not in s
    s[0], s[3] = 12.34, 56.78
    assert 12.34 in s
    assert isclose(s[0], 12.34) and isclose(s[3], 56.78)

    rev = reversed(s)
    assert cstats.values() == ['of size', '5']

    rev2 = s[::-1]
    assert cstats.values() == ['of size', '5']

    it = iter(Sequence(0))
    for _ in range(3):  # __next__ must continue to raise StopIteration
        with pytest.raises(StopIteration):
            next(it)
    assert cstats.values() == ['of size', '0']

    expected = [0, 56.78, 0, 0, 12.34]
    assert allclose(rev, expected)
    assert allclose(rev2, expected)
    assert rev == rev2

    rev[0::2] = Sequence([2.0, 2.0, 2.0])
    assert cstats.values() == ['of size', '3', 'from std::vector']

    assert allclose(rev, [2, 56.78, 2, 0, 2])

    assert cstats.alive() == 4
    del it
    assert cstats.alive() == 3
    del s
    assert cstats.alive() == 2
    del rev
    assert cstats.alive() == 1
    del rev2
    assert cstats.alive() == 0

    assert cstats.values() == []
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    assert cstats.move_constructions >= 1
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
Exemple #16
0
def test_instance(msg):
    with pytest.raises(TypeError) as excinfo:
        m.NoConstructor()
    assert msg(excinfo.value) == "m.class_.NoConstructor: No constructor defined!"

    instance = m.NoConstructor.new_instance()

    cstats = ConstructorStats.get(m.NoConstructor)
    assert cstats.alive() == 1
    del instance
    assert cstats.alive() == 0
Exemple #17
0
def test_enable_shared_from_this_with_reference_rvp():
    """ Issue #471: shared pointer instance not dellocated """
    from pybind11_tests import SharedParent, SharedChild

    parent = SharedParent()
    child = parent.get_child()

    cstats = ConstructorStats.get(SharedChild)
    assert cstats.alive() == 1
    del child, parent
    assert cstats.alive() == 0
def test_operator_overloading():
    from pybind11_tests import Vector2, Vector, ConstructorStats

    v1 = Vector2(1, 2)
    v2 = Vector(3, -1)
    assert str(v1) == "[1.000000, 2.000000]"
    assert str(v2) == "[3.000000, -1.000000]"

    assert str(v1 + v2) == "[4.000000, 1.000000]"
    assert str(v1 - v2) == "[-2.000000, 3.000000]"
    assert str(v1 - 8) == "[-7.000000, -6.000000]"
    assert str(v1 + 8) == "[9.000000, 10.000000]"
    assert str(v1 * 8) == "[8.000000, 16.000000]"
    assert str(v1 / 8) == "[0.125000, 0.250000]"
    assert str(8 - v1) == "[7.000000, 6.000000]"
    assert str(8 + v1) == "[9.000000, 10.000000]"
    assert str(8 * v1) == "[8.000000, 16.000000]"
    assert str(8 / v1) == "[8.000000, 4.000000]"
    assert str(v1 * v2) == "[3.000000, -2.000000]"
    assert str(v2 / v1) == "[3.000000, -0.500000]"

    v1 += 2 * v2
    assert str(v1) == "[7.000000, 0.000000]"
    v1 -= v2
    assert str(v1) == "[4.000000, 1.000000]"
    v1 *= 2
    assert str(v1) == "[8.000000, 2.000000]"
    v1 /= 16
    assert str(v1) == "[0.500000, 0.125000]"
    v1 *= v2
    assert str(v1) == "[1.500000, -0.125000]"
    v2 /= v1
    assert str(v2) == "[2.000000, 8.000000]"

    cstats = ConstructorStats.get(Vector2)
    assert cstats.alive() == 2
    del v1
    assert cstats.alive() == 1
    del v2
    assert cstats.alive() == 0
    assert cstats.values() == ['[1.000000, 2.000000]', '[3.000000, -1.000000]',
                               '[4.000000, 1.000000]', '[-2.000000, 3.000000]',
                               '[-7.000000, -6.000000]', '[9.000000, 10.000000]',
                               '[8.000000, 16.000000]', '[0.125000, 0.250000]',
                               '[7.000000, 6.000000]', '[9.000000, 10.000000]',
                               '[8.000000, 16.000000]', '[8.000000, 4.000000]',
                               '[3.000000, -2.000000]', '[3.000000, -0.500000]',
                               '[6.000000, -2.000000]']
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    assert cstats.move_constructions >= 10
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
Exemple #19
0
def test_move_only_holder_with_addressof_operator():
    a = m.TypeForMoveOnlyHolderWithAddressOf.make()
    a.print_object()

    stats = ConstructorStats.get(m.TypeForMoveOnlyHolderWithAddressOf)
    assert stats.alive() == 1

    a.value = 42
    assert a.value == 42

    del a
    assert stats.alive() == 0
def test_init_factory_basic():
    """Tests py::init_factory() wrapper around various ways of returning the object"""

    cstats = [ConstructorStats.get(c) for c in [m.TestFactory1, m.TestFactory2, m.TestFactory3]]
    cstats[0].alive()  # force gc
    n_inst = ConstructorStats.detail_reg_inst()

    x1 = m.TestFactory1(tag.unique_ptr, 3)
    assert x1.value == "3"
    y1 = m.TestFactory1(tag.pointer)
    assert y1.value == "(empty)"
    z1 = m.TestFactory1("hi!")
    assert z1.value == "hi!"

    assert ConstructorStats.detail_reg_inst() == n_inst + 3

    x2 = m.TestFactory2(tag.move)
    assert x2.value == "(empty2)"
    y2 = m.TestFactory2(tag.pointer, 7)
    assert y2.value == "7"
    z2 = m.TestFactory2(tag.unique_ptr, "hi again")
    assert z2.value == "hi again"

    assert ConstructorStats.detail_reg_inst() == n_inst + 6

    x3 = m.TestFactory3(tag.shared_ptr)
    assert x3.value == "(empty3)"
    y3 = m.TestFactory3(tag.pointer, 42)
    assert y3.value == "42"
    z3 = m.TestFactory3("bye")
    assert z3.value == "bye"

    with pytest.raises(TypeError) as excinfo:
        m.TestFactory3(tag.null_ptr)
    assert str(excinfo.value) == "pybind11::init(): factory function returned nullptr"

    assert [i.alive() for i in cstats] == [3, 3, 3]
    assert ConstructorStats.detail_reg_inst() == n_inst + 9

    del x1, y2, y3, z3
    assert [i.alive() for i in cstats] == [2, 2, 1]
    assert ConstructorStats.detail_reg_inst() == n_inst + 5
    del x2, x3, y1, z1, z2
    assert [i.alive() for i in cstats] == [0, 0, 0]
    assert ConstructorStats.detail_reg_inst() == n_inst

    assert [i.values() for i in cstats] == [
        ["3", "hi!"],
        ["7", "hi again"],
        ["42", "bye"]
    ]
    assert [i.default_constructions for i in cstats] == [1, 1, 1]
Exemple #21
0
def assert_keeps_alive(cl, method, *args):
    cstats = ConstructorStats.get(cl)
    start_with = cstats.alive()
    a = cl()
    assert cstats.alive() == start_with + 1
    z = method(a, *args)
    assert cstats.alive() == start_with + 1
    del a
    # Here's the keep alive in action:
    assert cstats.alive() == start_with + 1
    del z
    # Keep alive should have expired:
    assert cstats.alive() == start_with
def test_sequence():
    from pybind11_tests import Sequence, ConstructorStats

    cstats = ConstructorStats.get(Sequence)

    s = Sequence(5)
    assert cstats.values() == ['of size', '5']

    assert "Sequence" in repr(s)
    assert len(s) == 5
    assert s[0] == 0 and s[3] == 0
    assert 12.34 not in s
    s[0], s[3] = 12.34, 56.78
    assert 12.34 in s
    assert isclose(s[0], 12.34) and isclose(s[3], 56.78)

    rev = reversed(s)
    assert cstats.values() == ['of size', '5']

    rev2 = s[::-1]
    assert cstats.values() == ['of size', '5']

    expected = [0, 56.78, 0, 0, 12.34]
    assert allclose(rev, expected)
    assert allclose(rev2, expected)
    assert rev == rev2

    rev[0::2] = Sequence([2.0, 2.0, 2.0])
    assert cstats.values() == ['of size', '3', 'from std::vector']

    assert allclose(rev, [2, 56.78, 2, 0, 2])

    assert cstats.alive() == 3
    del s
    assert cstats.alive() == 2
    del rev
    assert cstats.alive() == 1
    del rev2
    assert cstats.alive() == 0

    assert cstats.values() == []
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    assert cstats.move_constructions >= 1
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
def test_cyclic_gc():
    # One object references itself
    instance = m.DynamicClass()
    instance.circular_reference = instance

    cstats = ConstructorStats.get(m.DynamicClass)
    assert cstats.alive() == 1
    del instance
    assert cstats.alive() == 0

    # Two object reference each other
    i1 = m.DynamicClass()
    i2 = m.DynamicClass()
    i1.cycle = i2
    i2.cycle = i1

    assert cstats.alive() == 2
    del i1, i2
    assert cstats.alive() == 0
def test_init_factory_casting():
    """Tests py::init_factory() wrapper with various upcasting and downcasting returns"""

    cstats = [ConstructorStats.get(c) for c in [m.TestFactory3, m.TestFactory4, m.TestFactory5]]
    cstats[0].alive()  # force gc
    n_inst = ConstructorStats.detail_reg_inst()

    # Construction from derived references:
    a = m.TestFactory3(tag.pointer, tag.TF4, 4)
    assert a.value == "4"
    b = m.TestFactory3(tag.shared_ptr, tag.TF4, 5)
    assert b.value == "5"
    c = m.TestFactory3(tag.pointer, tag.TF5, 6)
    assert c.value == "6"
    d = m.TestFactory3(tag.shared_ptr, tag.TF5, 7)
    assert d.value == "7"

    assert ConstructorStats.detail_reg_inst() == n_inst + 4

    # Shared a lambda with TF3:
    e = m.TestFactory4(tag.pointer, tag.TF4, 8)
    assert e.value == "8"

    assert ConstructorStats.detail_reg_inst() == n_inst + 5
    assert [i.alive() for i in cstats] == [5, 3, 2]

    del a
    assert [i.alive() for i in cstats] == [4, 2, 2]
    assert ConstructorStats.detail_reg_inst() == n_inst + 4

    del b, c, e
    assert [i.alive() for i in cstats] == [1, 0, 1]
    assert ConstructorStats.detail_reg_inst() == n_inst + 1

    del d
    assert [i.alive() for i in cstats] == [0, 0, 0]
    assert ConstructorStats.detail_reg_inst() == n_inst

    assert [i.values() for i in cstats] == [
        ["4", "5", "6", "7", "8"],
        ["4", "5", "8"],
        ["6", "7"]
    ]
Exemple #25
0
def test_eigen_keepalive():
    a = m.ReturnTester()
    cstats = ConstructorStats.get(m.ReturnTester)
    assert cstats.alive() == 1
    unsafe = [a.ref(), a.ref_const(), a.block(1, 2, 3, 4)]
    copies = [a.copy_get(), a.copy_view(), a.copy_ref(), a.copy_ref_const(),
              a.copy_block(4, 3, 2, 1)]
    del a
    assert cstats.alive() == 0
    del unsafe
    del copies

    for meth in [m.ReturnTester.get, m.ReturnTester.get_ptr, m.ReturnTester.view,
                 m.ReturnTester.view_ptr, m.ReturnTester.ref_safe, m.ReturnTester.ref_const_safe,
                 m.ReturnTester.corners, m.ReturnTester.corners_const]:
        assert_keeps_alive(m.ReturnTester, meth)

    for meth in [m.ReturnTester.block_safe, m.ReturnTester.block_const]:
        assert_keeps_alive(m.ReturnTester, meth, 4, 3, 2, 1)
def test_methods_and_attributes():
    instance1 = ExampleMandA()
    instance2 = ExampleMandA(32)

    instance1.add1(instance2)
    instance1.add2(instance2)
    instance1.add3(instance2)
    instance1.add4(instance2)
    instance1.add5(instance2)
    instance1.add6(32)
    instance1.add7(32)
    instance1.add8(32)
    instance1.add9(32)
    instance1.add10(32)

    assert str(instance1) == "ExampleMandA[value=320]"
    assert str(instance2) == "ExampleMandA[value=32]"
    assert str(instance1.self1()) == "ExampleMandA[value=320]"
    assert str(instance1.self2()) == "ExampleMandA[value=320]"
    assert str(instance1.self3()) == "ExampleMandA[value=320]"
    assert str(instance1.self4()) == "ExampleMandA[value=320]"
    assert str(instance1.self5()) == "ExampleMandA[value=320]"

    assert instance1.internal1() == 320
    assert instance1.internal2() == 320
    assert instance1.internal3() == 320
    assert instance1.internal4() == 320
    assert instance1.internal5() == 320

    assert instance1.value == 320
    instance1.value = 100
    assert str(instance1) == "ExampleMandA[value=100]"

    cstats = ConstructorStats.get(ExampleMandA)
    assert cstats.alive() == 2
    del instance1, instance2
    assert cstats.alive() == 0
    assert cstats.values() == ["32"]
    assert cstats.default_constructions == 1
    assert cstats.copy_constructions == 3
    assert cstats.move_constructions >= 1
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
Exemple #27
0
def test_eigen_keepalive():
    from pybind11_tests import ReturnTester, ConstructorStats
    a = ReturnTester()

    cstats = ConstructorStats.get(ReturnTester)
    assert cstats.alive() == 1
    unsafe = [a.ref(), a.ref_const(), a.block(1, 2, 3, 4)]
    copies = [a.copy_get(), a.copy_view(), a.copy_ref(), a.copy_ref_const(),
              a.copy_block(4, 3, 2, 1)]
    del a
    assert cstats.alive() == 0
    del unsafe
    del copies

    for meth in [ReturnTester.get, ReturnTester.get_ptr, ReturnTester.view,
                 ReturnTester.view_ptr, ReturnTester.ref_safe, ReturnTester.ref_const_safe,
                 ReturnTester.corners, ReturnTester.corners_const]:
        assert_keeps_alive(ReturnTester, meth)

    for meth in [ReturnTester.block_safe, ReturnTester.block_const]:
        assert_keeps_alive(ReturnTester, meth, 4, 3, 2, 1)
Exemple #28
0
def test_from_python():
    with pytest.raises(RuntimeError) as excinfo:
        Matrix(np.array([1, 2, 3]))  # trying to assign a 1D array
    assert str(excinfo.value) == "Incompatible buffer format!"

    m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
    m4 = Matrix(m3)

    for i in range(m4.rows()):
        for j in range(m4.cols()):
            assert m3[i, j] == m4[i, j]

    cstats = ConstructorStats.get(Matrix)
    assert cstats.alive() == 1
    del m3, m4
    assert cstats.alive() == 0
    assert cstats.values() == ["2x3 matrix"]
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0  # Don't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
def test_dynamic_attributes():
    from pybind11_tests import DynamicClass, CppDerivedDynamicClass

    instance = DynamicClass()
    assert not hasattr(instance, "foo")
    assert "foo" not in dir(instance)

    # Dynamically add attribute
    instance.foo = 42
    assert hasattr(instance, "foo")
    assert instance.foo == 42
    assert "foo" in dir(instance)

    # __dict__ should be accessible and replaceable
    assert "foo" in instance.__dict__
    instance.__dict__ = {"bar": True}
    assert not hasattr(instance, "foo")
    assert hasattr(instance, "bar")

    with pytest.raises(TypeError) as excinfo:
        instance.__dict__ = []
    assert str(excinfo.value) == "__dict__ must be set to a dictionary, not a 'list'"

    cstats = ConstructorStats.get(DynamicClass)
    assert cstats.alive() == 1
    del instance
    assert cstats.alive() == 0

    # Derived classes should work as well
    class PythonDerivedDynamicClass(DynamicClass):
        pass

    for cls in CppDerivedDynamicClass, PythonDerivedDynamicClass:
        derived = cls()
        derived.foobar = 100
        assert derived.foobar == 100

        assert cstats.alive() == 1
        del derived
        assert cstats.alive() == 0
Exemple #30
0
def test_shared_ptr_from_this_and_references():
    from pybind11_tests.smart_ptr import SharedFromThisRef, B, SharedFromThisVirt

    s = SharedFromThisRef()
    stats = ConstructorStats.get(B)
    assert stats.alive() == 2

    ref = s.ref  # init_holder_helper(holder_ptr=false, owned=false, bad_wp=false)
    assert stats.alive() == 2
    assert s.set_ref(ref)
    assert s.set_holder(ref)  # std::enable_shared_from_this can create a holder from a reference

    bad_wp = s.bad_wp  # init_holder_helper(holder_ptr=false, owned=false, bad_wp=true)
    assert stats.alive() == 2
    assert s.set_ref(bad_wp)
    with pytest.raises(RuntimeError) as excinfo:
        assert s.set_holder(bad_wp)
    assert "Unable to cast from non-held to held instance" in str(excinfo.value)

    copy = s.copy  # init_holder_helper(holder_ptr=false, owned=true, bad_wp=false)
    assert stats.alive() == 3
    assert s.set_ref(copy)
    assert s.set_holder(copy)

    holder_ref = s.holder_ref  # init_holder_helper(holder_ptr=true, owned=false, bad_wp=false)
    assert stats.alive() == 3
    assert s.set_ref(holder_ref)
    assert s.set_holder(holder_ref)

    holder_copy = s.holder_copy  # init_holder_helper(holder_ptr=true, owned=true, bad_wp=false)
    assert stats.alive() == 3
    assert s.set_ref(holder_copy)
    assert s.set_holder(holder_copy)

    del ref, bad_wp, copy, holder_ref, holder_copy, s
    assert stats.alive() == 0

    z = SharedFromThisVirt.get()
    y = SharedFromThisVirt.get()
    assert y is z
def test_smart_ptr(capture):
    # Object1
    from pybind11_tests import (MyObject1, make_object_1, make_object_2,
                                print_object_1, print_object_2, print_object_3,
                                print_object_4)

    for i, o in enumerate(
        [make_object_1(), make_object_2(),
         MyObject1(3)], start=1):
        assert o.getRefCount() == 1
        with capture:
            print_object_1(o)
            print_object_2(o)
            print_object_3(o)
            print_object_4(o)
        assert capture == "MyObject1[{i}]\n".format(i=i) * 4

    from pybind11_tests import (make_myobject1_1, make_myobject1_2,
                                print_myobject1_1, print_myobject1_2,
                                print_myobject1_3, print_myobject1_4)

    for i, o in enumerate(
        [make_myobject1_1(),
         make_myobject1_2(),
         MyObject1(6), 7], start=4):
        print(o)
        with capture:
            if not isinstance(o, int):
                print_object_1(o)
                print_object_2(o)
                print_object_3(o)
                print_object_4(o)
            print_myobject1_1(o)
            print_myobject1_2(o)
            print_myobject1_3(o)
            print_myobject1_4(o)
        assert capture == "MyObject1[{i}]\n".format(
            i=i) * (4 if isinstance(o, int) else 8)

    cstats = ConstructorStats.get(MyObject1)
    assert cstats.alive() == 0
    expected_values = ['MyObject1[{}]'.format(i)
                       for i in range(1, 7)] + ['MyObject1[7]'] * 4
    assert cstats.values() == expected_values
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0

    # Object2
    from pybind11_tests import (MyObject2, make_myobject2_1, make_myobject2_2,
                                make_myobject3_1, make_myobject3_2,
                                print_myobject2_1, print_myobject2_2,
                                print_myobject2_3, print_myobject2_4)

    for i, o in zip(
        [8, 6, 7],
        [MyObject2(8), make_myobject2_1(),
         make_myobject2_2()]):
        print(o)
        with capture:
            print_myobject2_1(o)
            print_myobject2_2(o)
            print_myobject2_3(o)
            print_myobject2_4(o)
        assert capture == "MyObject2[{i}]\n".format(i=i) * 4

    cstats = ConstructorStats.get(MyObject2)
    assert cstats.alive() == 1
    o = None
    assert cstats.alive() == 0
    assert cstats.values() == ['MyObject2[8]', 'MyObject2[6]', 'MyObject2[7]']
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0

    # Object3
    from pybind11_tests import (MyObject3, print_myobject3_1,
                                print_myobject3_2, print_myobject3_3,
                                print_myobject3_4)

    for i, o in zip(
        [9, 8, 9],
        [MyObject3(9), make_myobject3_1(),
         make_myobject3_2()]):
        print(o)
        with capture:
            print_myobject3_1(o)
            print_myobject3_2(o)
            print_myobject3_3(o)
            print_myobject3_4(o)
        assert capture == "MyObject3[{i}]\n".format(i=i) * 4

    cstats = ConstructorStats.get(MyObject3)
    assert cstats.alive() == 1
    o = None
    assert cstats.alive() == 0
    assert cstats.values() == ['MyObject3[9]', 'MyObject3[8]', 'MyObject3[9]']
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0

    # Object and ref
    from pybind11_tests import Object, cstats_ref

    cstats = ConstructorStats.get(Object)
    assert cstats.alive() == 0
    assert cstats.values() == []
    assert cstats.default_constructions == 10
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0

    cstats = cstats_ref()
    assert cstats.alive() == 0
    assert cstats.values() == ['from pointer'] * 10
    assert cstats.default_constructions == 30
    assert cstats.copy_constructions == 12
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 30
    assert cstats.move_assignments == 0
def test_operator_overloading():
    v1 = m.Vector2(1, 2)
    v2 = m.Vector(3, -1)
    v3 = m.Vector2(1, 2)  # Same value as v1, but different instance.
    assert v1 is not v3

    assert str(v1) == "[1.000000, 2.000000]"
    assert str(v2) == "[3.000000, -1.000000]"

    assert str(-v2) == "[-3.000000, 1.000000]"

    assert str(v1 + v2) == "[4.000000, 1.000000]"
    assert str(v1 - v2) == "[-2.000000, 3.000000]"
    assert str(v1 - 8) == "[-7.000000, -6.000000]"
    assert str(v1 + 8) == "[9.000000, 10.000000]"
    assert str(v1 * 8) == "[8.000000, 16.000000]"
    assert str(v1 / 8) == "[0.125000, 0.250000]"
    assert str(8 - v1) == "[7.000000, 6.000000]"
    assert str(8 + v1) == "[9.000000, 10.000000]"
    assert str(8 * v1) == "[8.000000, 16.000000]"
    assert str(8 / v1) == "[8.000000, 4.000000]"
    assert str(v1 * v2) == "[3.000000, -2.000000]"
    assert str(v2 / v1) == "[3.000000, -0.500000]"

    assert v1 == v3
    assert v1 != v2
    assert hash(v1) == 4
    # TODO(eric.cousineau): Make this work.
    # assert abs(v1) == "abs(Vector2)"

    v1 += 2 * v2
    assert str(v1) == "[7.000000, 0.000000]"
    v1 -= v2
    assert str(v1) == "[4.000000, 1.000000]"
    v1 *= 2
    assert str(v1) == "[8.000000, 2.000000]"
    v1 /= 16
    assert str(v1) == "[0.500000, 0.125000]"
    v1 *= v2
    assert str(v1) == "[1.500000, -0.125000]"
    v2 /= v1
    assert str(v2) == "[2.000000, 8.000000]"

    cstats = ConstructorStats.get(m.Vector2)
    assert cstats.alive() == 3
    del v1
    assert cstats.alive() == 2
    del v2
    assert cstats.alive() == 1
    del v3
    assert cstats.alive() == 0
    assert cstats.values() == [
        "[1.000000, 2.000000]",
        "[3.000000, -1.000000]",
        "[1.000000, 2.000000]",
        "[-3.000000, 1.000000]",
        "[4.000000, 1.000000]",
        "[-2.000000, 3.000000]",
        "[-7.000000, -6.000000]",
        "[9.000000, 10.000000]",
        "[8.000000, 16.000000]",
        "[0.125000, 0.250000]",
        "[7.000000, 6.000000]",
        "[9.000000, 10.000000]",
        "[8.000000, 16.000000]",
        "[8.000000, 4.000000]",
        "[3.000000, -2.000000]",
        "[3.000000, -0.500000]",
        "[6.000000, -2.000000]",
    ]
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    assert cstats.move_constructions >= 10
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0
def test_methods_and_attributes():
    instance1 = ExampleMandA()
    instance2 = ExampleMandA(32)

    instance1.add1(instance2)
    instance1.add2(instance2)
    instance1.add3(instance2)
    instance1.add4(instance2)
    instance1.add5(instance2)
    instance1.add6(32)
    instance1.add7(32)
    instance1.add8(32)
    instance1.add9(32)
    instance1.add10(32)

    if str(instance1) != "ExampleMandA[value=320]":
        raise AssertionError
    if str(instance2) != "ExampleMandA[value=32]":
        raise AssertionError
    if str(instance1.self1()) != "ExampleMandA[value=320]":
        raise AssertionError
    if str(instance1.self2()) != "ExampleMandA[value=320]":
        raise AssertionError
    if str(instance1.self3()) != "ExampleMandA[value=320]":
        raise AssertionError
    if str(instance1.self4()) != "ExampleMandA[value=320]":
        raise AssertionError
    if str(instance1.self5()) != "ExampleMandA[value=320]":
        raise AssertionError

    if instance1.internal1() != 320:
        raise AssertionError
    if instance1.internal2() != 320:
        raise AssertionError
    if instance1.internal3() != 320:
        raise AssertionError
    if instance1.internal4() != 320:
        raise AssertionError
    if instance1.internal5() != 320:
        raise AssertionError

    if instance1.overloaded(1, 1.0) != "(int, float)":
        raise AssertionError
    if instance1.overloaded(2.0, 2) != "(float, int)":
        raise AssertionError
    if instance1.overloaded(3, 3) != "(int, int)":
        raise AssertionError
    if instance1.overloaded(4., 4.) != "(float, float)":
        raise AssertionError
    if instance1.overloaded_const(5, 5.0) != "(int, float) const":
        raise AssertionError
    if instance1.overloaded_const(6.0, 6) != "(float, int) const":
        raise AssertionError
    if instance1.overloaded_const(7, 7) != "(int, int) const":
        raise AssertionError
    if instance1.overloaded_const(8., 8.) != "(float, float) const":
        raise AssertionError
    if instance1.overloaded_float(1, 1) != "(float, float)":
        raise AssertionError
    if instance1.overloaded_float(1, 1.) != "(float, float)":
        raise AssertionError
    if instance1.overloaded_float(1., 1) != "(float, float)":
        raise AssertionError
    if instance1.overloaded_float(1., 1.) != "(float, float)":
        raise AssertionError

    if instance1.value != 320:
        raise AssertionError
    instance1.value = 100
    if str(instance1) != "ExampleMandA[value=100]":
        raise AssertionError

    cstats = ConstructorStats.get(ExampleMandA)
    if cstats.alive() != 2:
        raise AssertionError
    del instance1, instance2
    if cstats.alive() != 0:
        raise AssertionError
    if cstats.values() != ["32"]:
        raise AssertionError
    if cstats.default_constructions != 1:
        raise AssertionError
    if cstats.copy_constructions != 3:
        raise AssertionError
    if cstats.move_constructions < 1:
        raise AssertionError
    if cstats.copy_assignments != 0:
        raise AssertionError
    if cstats.move_assignments != 0:
        raise AssertionError
Exemple #34
0
def test_smart_ptr(capture):
    # Object1
    for i, o in enumerate(
        [m.make_object_1(),
         m.make_object_2(),
         m.MyObject1(3)], start=1):
        assert o.getRefCount() == 1
        with capture:
            m.print_object_1(o)
            m.print_object_2(o)
            m.print_object_3(o)
            m.print_object_4(o)
        assert capture == "MyObject1[{i}]\n".format(i=i) * 4

    for i, o in enumerate(
        [m.make_myobject1_1(),
         m.make_myobject1_2(),
         m.MyObject1(6), 7],
            start=4):
        print(o)
        with capture:
            if not isinstance(o, int):
                m.print_object_1(o)
                m.print_object_2(o)
                m.print_object_3(o)
                m.print_object_4(o)
            m.print_myobject1_1(o)
            m.print_myobject1_2(o)
            m.print_myobject1_3(o)
            m.print_myobject1_4(o)
        assert capture == "MyObject1[{i}]\n".format(
            i=i) * (4 if isinstance(o, int) else 8)

    cstats = ConstructorStats.get(m.MyObject1)
    assert cstats.alive() == 0
    expected_values = ["MyObject1[{}]".format(i)
                       for i in range(1, 7)] + ["MyObject1[7]"] * 4
    assert cstats.values() == expected_values
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0

    # Object2
    for i, o in zip(
        [8, 6, 7],
        [m.MyObject2(8),
         m.make_myobject2_1(),
         m.make_myobject2_2()]):
        print(o)
        with capture:
            m.print_myobject2_1(o)
            m.print_myobject2_2(o)
            m.print_myobject2_3(o)
            m.print_myobject2_4(o)
        assert capture == "MyObject2[{i}]\n".format(i=i) * 4

    cstats = ConstructorStats.get(m.MyObject2)
    assert cstats.alive() == 1
    o = None
    assert cstats.alive() == 0
    assert cstats.values() == ["MyObject2[8]", "MyObject2[6]", "MyObject2[7]"]
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0

    # Object3
    for i, o in zip(
        [9, 8, 9],
        [m.MyObject3(9),
         m.make_myobject3_1(),
         m.make_myobject3_2()]):
        print(o)
        with capture:
            m.print_myobject3_1(o)
            m.print_myobject3_2(o)
            m.print_myobject3_3(o)
            m.print_myobject3_4(o)
        assert capture == "MyObject3[{i}]\n".format(i=i) * 4

    cstats = ConstructorStats.get(m.MyObject3)
    assert cstats.alive() == 1
    o = None
    assert cstats.alive() == 0
    assert cstats.values() == ["MyObject3[9]", "MyObject3[8]", "MyObject3[9]"]
    assert cstats.default_constructions == 0
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0

    # Object
    cstats = ConstructorStats.get(m.Object)
    assert cstats.alive() == 0
    assert cstats.values() == []
    assert cstats.default_constructions == 10
    assert cstats.copy_constructions == 0
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 0
    assert cstats.move_assignments == 0

    # ref<>
    cstats = m.cstats_ref()
    assert cstats.alive() == 0
    assert cstats.values() == ["from pointer"] * 10
    assert cstats.default_constructions == 30
    assert cstats.copy_constructions == 12
    # assert cstats.move_constructions >= 0 # Doesn't invoke any
    assert cstats.copy_assignments == 30
    assert cstats.move_assignments == 0
Exemple #35
0
def test_override(capture, msg):
    class ExtendedExampleVirt(m.ExampleVirt):
        def __init__(self, state):
            super(ExtendedExampleVirt, self).__init__(state + 1)
            self.data = "Hello world"

        def run(self, value):
            print("ExtendedExampleVirt::run(%i), calling parent.." % value)
            return super(ExtendedExampleVirt, self).run(value + 1)

        def run_bool(self):
            print("ExtendedExampleVirt::run_bool()")
            return False

        def get_string1(self):
            return "override1"

        def pure_virtual(self):
            print("ExtendedExampleVirt::pure_virtual(): %s" % self.data)

    class ExtendedExampleVirt2(ExtendedExampleVirt):
        def __init__(self, state):
            super(ExtendedExampleVirt2, self).__init__(state + 1)

        def get_string2(self):
            return "override2"

    ex12 = m.ExampleVirt(10)
    with capture:
        assert m.runExampleVirt(ex12, 20) == 30
    assert (capture == """
        Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2)
    """

            # noqa: E501 line too long
            )

    with pytest.raises(RuntimeError) as excinfo:
        m.runExampleVirtVirtual(ex12)
    assert (msg(excinfo.value) ==
            'Tried to call pure virtual function "ExampleVirt::pure_virtual"')

    ex12p = ExtendedExampleVirt(10)
    with capture:
        assert m.runExampleVirt(ex12p, 20) == 32
    assert (capture == """
        ExtendedExampleVirt::run(20), calling parent..
        Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2)
    """

            # noqa: E501 line too long
            )
    with capture:
        assert m.runExampleVirtBool(ex12p) is False
    assert capture == "ExtendedExampleVirt::run_bool()"
    with capture:
        m.runExampleVirtVirtual(ex12p)
    assert capture == "ExtendedExampleVirt::pure_virtual(): Hello world"

    ex12p2 = ExtendedExampleVirt2(15)
    with capture:
        assert m.runExampleVirt(ex12p2, 50) == 68
    assert (capture == """
        ExtendedExampleVirt::run(50), calling parent..
        Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2)
    """

            # noqa: E501 line too long
            )

    cstats = ConstructorStats.get(m.ExampleVirt)
    assert cstats.alive() == 3
    del ex12, ex12p, ex12p2
    assert cstats.alive() == 0
    assert cstats.values() == ["10", "11", "17"]
    assert cstats.copy_constructions == 0
    assert cstats.move_constructions >= 0
def test_init_factory_basic():
    """Tests py::init_factory() wrapper around various ways of returning the object"""

    cstats = [
        ConstructorStats.get(c)
        for c in [m.TestFactory1, m.TestFactory2, m.TestFactory3]
    ]
    cstats[0].alive()  # force gc
    n_inst = ConstructorStats.detail_reg_inst()

    x1 = m.TestFactory1(tag.unique_ptr, 3)
    assert x1.value == "3"
    y1 = m.TestFactory1(tag.pointer)
    assert y1.value == "(empty)"
    z1 = m.TestFactory1("hi!")
    assert z1.value == "hi!"

    assert ConstructorStats.detail_reg_inst() == n_inst + 3

    x2 = m.TestFactory2(tag.move)
    assert x2.value == "(empty2)"
    y2 = m.TestFactory2(tag.pointer, 7)
    assert y2.value == "7"
    z2 = m.TestFactory2(tag.unique_ptr, "hi again")
    assert z2.value == "hi again"

    assert ConstructorStats.detail_reg_inst() == n_inst + 6

    x3 = m.TestFactory3(tag.shared_ptr)
    assert x3.value == "(empty3)"
    y3 = m.TestFactory3(tag.pointer, 42)
    assert y3.value == "42"
    z3 = m.TestFactory3("bye")
    assert z3.value == "bye"

    for null_ptr_kind in [
            tag.null_ptr,
            tag.null_unique_ptr,
            tag.null_shared_ptr,
    ]:
        with pytest.raises(TypeError) as excinfo:
            m.TestFactory3(null_ptr_kind)
        assert (str(excinfo.value) ==
                "pybind11::init(): factory function returned nullptr")

    assert [i.alive() for i in cstats] == [3, 3, 3]
    assert ConstructorStats.detail_reg_inst() == n_inst + 9

    del x1, y2, y3, z3
    assert [i.alive() for i in cstats] == [2, 2, 1]
    assert ConstructorStats.detail_reg_inst() == n_inst + 5
    del x2, x3, y1, z1, z2
    assert [i.alive() for i in cstats] == [0, 0, 0]
    assert ConstructorStats.detail_reg_inst() == n_inst

    assert [i.values() for i in cstats] == [
        ["3", "hi!"],
        ["7", "hi again"],
        ["42", "bye"],
    ]
    assert [i.default_constructions for i in cstats] == [1, 1, 1]
def test_sequence():
    from pybind11_tests import Sequence, ConstructorStats

    cstats = ConstructorStats.get(Sequence)

    s = Sequence(5)
    if cstats.values() != ['of size', '5']:
        raise AssertionError

    if "Sequence" not in repr(s):
        raise AssertionError
    if len(s) != 5:
        raise AssertionError
    if not (s[0] == 0 and s[3] == 0):
        raise AssertionError
    if 12.34 in s:
        raise AssertionError
    s[0], s[3] = 12.34, 56.78
    if 12.34 not in s:
        raise AssertionError
    if not (isclose(s[0], 12.34) and isclose(s[3], 56.78)):
        raise AssertionError

    rev = reversed(s)
    if cstats.values() != ['of size', '5']:
        raise AssertionError

    rev2 = s[::-1]
    if cstats.values() != ['of size', '5']:
        raise AssertionError

    expected = [0, 56.78, 0, 0, 12.34]
    if not allclose(rev, expected):
        raise AssertionError
    if not allclose(rev2, expected):
        raise AssertionError
    if rev != rev2:
        raise AssertionError

    rev[0::2] = Sequence([2.0, 2.0, 2.0])
    if cstats.values() != ['of size', '3', 'from std::vector']:
        raise AssertionError

    if not allclose(rev, [2, 56.78, 2, 0, 2]):
        raise AssertionError

    if cstats.alive() != 3:
        raise AssertionError
    del s
    if cstats.alive() != 2:
        raise AssertionError
    del rev
    if cstats.alive() != 1:
        raise AssertionError
    del rev2
    if cstats.alive() != 0:
        raise AssertionError

    if cstats.values() != []:
        raise AssertionError
    if cstats.default_constructions != 0:
        raise AssertionError
    if cstats.copy_constructions != 0:
        raise AssertionError
    if cstats.move_constructions < 1:
        raise AssertionError
    if cstats.copy_assignments != 0:
        raise AssertionError
    if cstats.move_assignments != 0:
        raise AssertionError
Exemple #38
0
def test_move_only_holder():
    a = m.TypeWithMoveOnlyHolder.make()
    stats = ConstructorStats.get(m.TypeWithMoveOnlyHolder)
    assert stats.alive() == 1
    del a
    assert stats.alive() == 0
Exemple #39
0
def test_instance(capture):
    with pytest.raises(TypeError) as excinfo:
        ExamplePythonTypes()
    assert str(excinfo.value) == "pybind11_tests.ExamplePythonTypes: No constructor defined!"

    instance = ExamplePythonTypes.new_instance()

    with capture:
        dict_result = instance.get_dict()
        dict_result['key2'] = 'value2'
        instance.print_dict(dict_result)
    assert capture.unordered == """
        key: key, value=value
        key: key2, value=value2
    """
    with capture:
        dict_result = instance.get_dict_2()
        dict_result['key2'] = 'value2'
        instance.print_dict_2(dict_result)
    assert capture.unordered == """
        key: key, value=value
        key: key2, value=value2
    """
    with capture:
        set_result = instance.get_set()
        set_result.add('key4')
        instance.print_set(set_result)
    assert capture.unordered == """
        key: key1
        key: key2
        key: key3
        key: key4
    """
    with capture:
        set_result = instance.get_set2()
        set_result.add('key3')
        instance.print_set_2(set_result)
    assert capture.unordered == """
        key: key1
        key: key2
        key: key3
    """
    with capture:
        list_result = instance.get_list()
        list_result.append('value2')
        instance.print_list(list_result)
    assert capture.unordered == """
        Entry at position 0: value
        list item 0: overwritten
        list item 1: value2
    """
    with capture:
        list_result = instance.get_list_2()
        list_result.append('value2')
        instance.print_list_2(list_result)
    assert capture.unordered == """
        list item 0: value
        list item 1: value2
    """
    with capture:
        list_result = instance.get_list_2()
        list_result.append('value2')
        instance.print_list_2(tuple(list_result))
    assert capture.unordered == """
        list item 0: value
        list item 1: value2
    """
    array_result = instance.get_array()
    assert array_result == ['array entry 1', 'array entry 2']
    with capture:
        instance.print_array(array_result)
    assert capture.unordered == """
        array item 0: array entry 1
        array item 1: array entry 2
    """
    varray_result = instance.get_valarray()
    assert varray_result == [1, 4, 9]
    with capture:
        instance.print_valarray(varray_result)
    assert capture.unordered == """
        valarray item 0: 1
        valarray item 1: 4
        valarray item 2: 9
    """
    with pytest.raises(RuntimeError) as excinfo:
        instance.throw_exception()
    assert str(excinfo.value) == "This exception was intentionally thrown."

    assert instance.pair_passthrough((True, "test")) == ("test", True)
    assert instance.tuple_passthrough((True, "test", 5)) == (5, "test", True)
    # Any sequence can be cast to a std::pair or std::tuple
    assert instance.pair_passthrough([True, "test"]) == ("test", True)
    assert instance.tuple_passthrough([True, "test", 5]) == (5, "test", True)

    assert instance.get_bytes_from_string().decode() == "foo"
    assert instance.get_bytes_from_str().decode() == "bar"
    assert instance.get_str_from_string().encode().decode() == "baz"
    assert instance.get_str_from_bytes().encode().decode() == "boo"

    class A(object):
        def __str__(self):
            return "this is a str"

        def __repr__(self):
            return "this is a repr"

    with capture:
        instance.test_print(A())
    assert capture == """
        this is a str
        this is a repr
    """

    cstats = ConstructorStats.get(ExamplePythonTypes)
    assert cstats.alive() == 1
    del instance
    assert cstats.alive() == 0
Exemple #40
0
def test_instance_new(msg):
    instance = m.NoConstructorNew()  # .__new__(m.NoConstructor.__class__)
    cstats = ConstructorStats.get(m.NoConstructorNew)
    assert cstats.alive() == 1
    del instance
    assert cstats.alive() == 0