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]"
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
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
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
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
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
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
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
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
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
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
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]
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"] ]
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
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)
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
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
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
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
def test_move_only_holder(): a = m.TypeWithMoveOnlyHolder.make() stats = ConstructorStats.get(m.TypeWithMoveOnlyHolder) assert stats.alive() == 1 del a assert stats.alive() == 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
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