def test_return_none(capture): n_inst = ConstructorStats.detail_reg_inst() with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.returnNullChildKeepAliveChild() assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert capture == "" with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent." with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.returnNullChildKeepAliveParent() assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert capture == "" with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent."
def test_keep_alive_return_value(capture): from pybind11_tests import Parent, ConstructorStats n_inst = ConstructorStats.detail_reg_inst() with capture: p = Parent() assert capture == "Allocating parent." with capture: p.returnChild() assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert capture == """ Allocating child. Releasing child. """ with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent." with capture: p = Parent() assert capture == "Allocating parent." with capture: p.returnChildKeepAlive() assert ConstructorStats.detail_reg_inst() == n_inst + 2 assert capture == "Allocating child." with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_keep_alive_return_value(capture): n_inst = ConstructorStats.detail_reg_inst() with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.returnChild() assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert (capture == """ Allocating child. Releasing child. """) with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent." with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.returnChildKeepAlive() assert ConstructorStats.detail_reg_inst() == n_inst + 2 assert capture == "Allocating child." with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert (capture == """ Releasing parent. Releasing child. """)
def test_keep_alive_return_value(capture): from pybind11_tests import Parent, ConstructorStats n_inst = ConstructorStats.detail_reg_inst() with capture: p = Parent() assert capture == "Allocating parent." with capture: p.returnChild() assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert capture == """ Allocating child. Releasing child. """ with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent." with capture: p = Parent() assert capture == "Allocating parent." with capture: p.returnChildKeepAlive() assert ConstructorStats.detail_reg_inst() == n_inst + 2 assert capture == "Allocating child." with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_mi_unaligned_base(): """Returning an offset (non-first MI) base class pointer should recognize the instance""" from pybind11_tests import I801C, I801D, i801b1_c, i801b2_c, i801b1_d, i801b2_d n_inst = ConstructorStats.detail_reg_inst() c = I801C() d = I801D() # + 4 below because we have the two instances, and each instance has offset base I801B2 assert ConstructorStats.detail_reg_inst() == n_inst + 4 b1c = i801b1_c(c) assert b1c is c b2c = i801b2_c(c) assert b2c is c b1d = i801b1_d(d) assert b1d is d b2d = i801b2_d(d) assert b2d is d assert ConstructorStats.detail_reg_inst( ) == n_inst + 4 # no extra instances del c, b1c, b2c assert ConstructorStats.detail_reg_inst() == n_inst + 2 del d, b1d, b2d assert ConstructorStats.detail_reg_inst() == n_inst
def test_keep_alive_argument(capture): n_inst = ConstructorStats.detail_reg_inst() with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.addChild(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert capture == """ Allocating child. Releasing child. """ with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent." with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.addChildKeepAlive(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 assert capture == "Allocating child." with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_keep_alive_argument(capture): n_inst = ConstructorStats.detail_reg_inst() with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.addChild(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert capture == """ Allocating child. Releasing child. """ with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent." with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.addChildKeepAlive(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 assert capture == "Allocating child." with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_return_none(capture): n_inst = ConstructorStats.detail_reg_inst() with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.returnNullChildKeepAliveChild() assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert capture == "" with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent." with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.returnNullChildKeepAliveParent() assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert capture == "" with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent."
def test_alive_gc(capture): n_inst = ConstructorStats.detail_reg_inst() p = m.ParentGC() p.addChildKeepAlive(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_alive_gc(capture): n_inst = ConstructorStats.detail_reg_inst() p = m.ParentGC() p.addChildKeepAlive(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_alive_gc(capture): from pybind11_tests import ParentGC, Child, ConstructorStats n_inst = ConstructorStats.detail_reg_inst() p = ParentGC() p.addChildKeepAlive(Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_alive_gc(capture): from pybind11_tests import ParentGC, Child, ConstructorStats n_inst = ConstructorStats.detail_reg_inst() p = ParentGC() p.addChildKeepAlive(Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_keep_alive_constructor(capture): n_inst = ConstructorStats.detail_reg_inst() with capture: p = m.Parent(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 assert capture == """ Allocating child. Allocating parent. """ with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_keep_alive_constructor(capture): n_inst = ConstructorStats.detail_reg_inst() with capture: p = m.Parent(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 assert capture == """ Allocating child. Allocating parent. """ with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_mi_base_return(): """Tests returning an offset (non-first MI) base class pointer to a derived instance""" from pybind11_tests import (I801B2, I801C, I801D, i801c_b1, i801c_b2, i801d_b1, i801d_b2, i801e_c, i801e_b2) n_inst = ConstructorStats.detail_reg_inst() c1 = i801c_b1() assert type(c1) is I801C assert c1.a == 1 assert c1.b == 2 d1 = i801d_b1() assert type(d1) is I801D assert d1.a == 1 assert d1.b == 2 assert ConstructorStats.detail_reg_inst() == n_inst + 4 c2 = i801c_b2() assert type(c2) is I801C assert c2.a == 1 assert c2.b == 2 d2 = i801d_b2() assert type(d2) is I801D assert d2.a == 1 assert d2.b == 2 assert ConstructorStats.detail_reg_inst() == n_inst + 8 del c2 assert ConstructorStats.detail_reg_inst() == n_inst + 6 del c1, d1, d2 assert ConstructorStats.detail_reg_inst() == n_inst # Returning an unregistered derived type with a registered base; we won't # pick up the derived type, obviously, but should still work (as an object # of whatever type was returned). e1 = i801e_c() assert type(e1) is I801C assert e1.a == 1 assert e1.b == 2 e2 = i801e_b2() assert type(e2) is I801B2 assert e2.b == 2
def test_mi_base_return(): """Tests returning an offset (non-first MI) base class pointer to a derived instance""" from pybind11_tests import (I801B2, I801C, I801D, i801c_b1, i801c_b2, i801d_b1, i801d_b2, i801e_c, i801e_b2) n_inst = ConstructorStats.detail_reg_inst() c1 = i801c_b1() assert type(c1) is I801C assert c1.a == 1 assert c1.b == 2 d1 = i801d_b1() assert type(d1) is I801D assert d1.a == 1 assert d1.b == 2 assert ConstructorStats.detail_reg_inst() == n_inst + 4 c2 = i801c_b2() assert type(c2) is I801C assert c2.a == 1 assert c2.b == 2 d2 = i801d_b2() assert type(d2) is I801D assert d2.a == 1 assert d2.b == 2 assert ConstructorStats.detail_reg_inst() == n_inst + 8 del c2 assert ConstructorStats.detail_reg_inst() == n_inst + 6 del c1, d1, d2 assert ConstructorStats.detail_reg_inst() == n_inst # Returning an unregistered derived type with a registered base; we won't # pick up the derived type, obviously, but should still work (as an object # of whatever type was returned). e1 = i801e_c() assert type(e1) is I801C assert e1.a == 1 assert e1.b == 2 e2 = i801e_b2() assert type(e2) is I801B2 assert e2.b == 2
def test_alive_gc_multi_derived(capture): from pybind11_tests import Parent, Child, ConstructorStats class Derived(Parent, Child): pass n_inst = ConstructorStats.detail_reg_inst() p = Derived() p.addChildKeepAlive(Child()) # +3 rather than +2 because Derived corresponds to two registered instances assert ConstructorStats.detail_reg_inst() == n_inst + 3 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_alive_gc_multi_derived(capture): from pybind11_tests import Parent, Child, ConstructorStats class Derived(Parent, Child): pass n_inst = ConstructorStats.detail_reg_inst() p = Derived() p.addChildKeepAlive(Child()) # +3 rather than +2 because Derived corresponds to two registered instances assert ConstructorStats.detail_reg_inst() == n_inst + 3 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_operator_new_delete(capture): """Tests that class-specific operator new/delete functions are invoked""" class SubAliased(m.AliasedHasOpNewDelSize): pass with capture: a = m.HasOpNewDel() b = m.HasOpNewDelSize() d = m.HasOpNewDelBoth() assert capture == """ A new 8 A placement-new 8 B new 4 B placement-new 4 D new 32 D placement-new 32 """ sz_alias = str(m.AliasedHasOpNewDelSize.size_alias) sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias) with capture: c = m.AliasedHasOpNewDelSize() c2 = SubAliased() assert capture == ("C new " + sz_alias + "\nC placement-new " + sz_noalias + "\n" + "C new " + sz_alias + "\nC placement-new " + sz_alias + "\n") with capture: del a ConstructorStats.detail_reg_inst() del b ConstructorStats.detail_reg_inst() del d ConstructorStats.detail_reg_inst() assert capture == """ A delete B delete 4 D delete """ with capture: del c ConstructorStats.detail_reg_inst() del c2 ConstructorStats.detail_reg_inst() assert capture == ("C delete " + sz_noalias + "\n" + "C delete " + sz_alias + "\n")
def test_alive_gc_derived(capture): class Derived(m.Parent): pass n_inst = ConstructorStats.detail_reg_inst() p = Derived() p.addChildKeepAlive(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert (capture == """ Releasing parent. Releasing child. """)
def test_alive_gc_multi_derived(capture): class Derived(m.Parent, m.Child): def __init__(self): m.Parent.__init__(self) m.Child.__init__(self) n_inst = ConstructorStats.detail_reg_inst() p = Derived() p.addChildKeepAlive(m.Child()) # +3 rather than +2 because Derived corresponds to two registered instances assert ConstructorStats.detail_reg_inst() == n_inst + 3 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
def test_alive_gc_multi_derived(capture): class Derived(m.Parent, m.Child): def __init__(self): m.Parent.__init__(self) m.Child.__init__(self) n_inst = ConstructorStats.detail_reg_inst() p = Derived() p.addChildKeepAlive(m.Child()) # +3 rather than +2 because Derived corresponds to two registered instances assert ConstructorStats.detail_reg_inst() == n_inst + 3 lst = [p] lst.append(lst) # creates a circular reference with capture: del p, lst assert ConstructorStats.detail_reg_inst() == n_inst assert capture == """
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_mi_unaligned_base(): """Returning an offset (non-first MI) base class pointer should recognize the instance""" n_inst = ConstructorStats.detail_reg_inst() c = m.I801C() d = m.I801D() # + 4 below because we have the two instances, and each instance has offset base I801B2 assert ConstructorStats.detail_reg_inst() == n_inst + 4 b1c = m.i801b1_c(c) assert b1c is c b2c = m.i801b2_c(c) assert b2c is c b1d = m.i801b1_d(d) assert b1d is d b2d = m.i801b2_d(d) assert b2d is d assert ConstructorStats.detail_reg_inst() == n_inst + 4 # no extra instances del c, b1c, b2c assert ConstructorStats.detail_reg_inst() == n_inst + 2 del d, b1d, b2d assert ConstructorStats.detail_reg_inst() == n_inst
def test_keep_alive_argument(capture): n_inst = ConstructorStats.detail_reg_inst() with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.addChild(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 1 assert (capture == """ Allocating child. Releasing child. """) with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert capture == "Releasing parent." with capture: p = m.Parent() assert capture == "Allocating parent." with capture: p.addChildKeepAlive(m.Child()) assert ConstructorStats.detail_reg_inst() == n_inst + 2 assert capture == "Allocating child." with capture: del p assert ConstructorStats.detail_reg_inst() == n_inst assert (capture == """ Releasing parent. Releasing child. """) p = m.Parent() c = m.Child() assert ConstructorStats.detail_reg_inst() == n_inst + 2 m.free_function(p, c) del c assert ConstructorStats.detail_reg_inst() == n_inst + 2 del p assert ConstructorStats.detail_reg_inst() == n_inst with pytest.raises(RuntimeError) as excinfo: m.invalid_arg_index() assert str(excinfo.value) == "Could not activate keep_alive!"
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 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_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_init_factory_alias(): """Tests py::init_factory() wrapper with value conversions and alias types""" cstats = [m.TestFactory6.get_cstats(), m.TestFactory6.get_alias_cstats()] cstats[0].alive() # force gc n_inst = ConstructorStats.detail_reg_inst() a = m.TestFactory6(tag.base, 1) assert a.get() == 1 assert not a.has_alias() b = m.TestFactory6(tag.alias, "hi there") assert b.get() == 8 assert b.has_alias() c = m.TestFactory6(tag.alias, 3) assert c.get() == 3 assert c.has_alias() d = m.TestFactory6(tag.alias, tag.pointer, 4) assert d.get() == 4 assert d.has_alias() e = m.TestFactory6(tag.base, tag.pointer, 5) assert e.get() == 5 assert not e.has_alias() f = m.TestFactory6(tag.base, tag.alias, tag.pointer, 6) assert f.get() == 6 assert f.has_alias() assert ConstructorStats.detail_reg_inst() == n_inst + 6 assert [i.alive() for i in cstats] == [6, 4] del a, b, e assert [i.alive() for i in cstats] == [3, 3] assert ConstructorStats.detail_reg_inst() == n_inst + 3 del f, c, d assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst class MyTest(m.TestFactory6): def __init__(self, *args): m.TestFactory6.__init__(self, *args) def get(self): return -5 + m.TestFactory6.get(self) # Return Class by value, moved into new alias: z = MyTest(tag.base, 123) assert z.get() == 118 assert z.has_alias() # Return alias by value, moved into new alias: y = MyTest(tag.alias, "why hello!") assert y.get() == 5 assert y.has_alias() # Return Class by pointer, moved into new alias then original destroyed: x = MyTest(tag.base, tag.pointer, 47) assert x.get() == 42 assert x.has_alias() assert ConstructorStats.detail_reg_inst() == n_inst + 3 assert [i.alive() for i in cstats] == [3, 3] del x, y, z assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst assert [i.values() for i in cstats] == [[ "1", "8", "3", "4", "5", "6", "123", "10", "47" ], ["hi there", "3", "4", "6", "move", "123", "why hello!", "move", "47"]]
def test_init_factory_dual(): """Tests init factory functions with dual main/alias factory functions""" from pybind11_tests.factory_constructors import TestFactory7 cstats = [TestFactory7.get_cstats(), TestFactory7.get_alias_cstats()] cstats[0].alive() # force gc n_inst = ConstructorStats.detail_reg_inst() class PythFactory7(TestFactory7): def get(self): return 100 + TestFactory7.get(self) a1 = TestFactory7(1) a2 = PythFactory7(2) assert a1.get() == 1 assert a2.get() == 102 assert not a1.has_alias() assert a2.has_alias() b1 = TestFactory7(tag.pointer, 3) b2 = PythFactory7(tag.pointer, 4) assert b1.get() == 3 assert b2.get() == 104 assert not b1.has_alias() assert b2.has_alias() c1 = TestFactory7(tag.mixed, 5) c2 = PythFactory7(tag.mixed, 6) assert c1.get() == 5 assert c2.get() == 106 assert not c1.has_alias() assert c2.has_alias() d1 = TestFactory7(tag.base, tag.pointer, 7) d2 = PythFactory7(tag.base, tag.pointer, 8) assert d1.get() == 7 assert d2.get() == 108 assert not d1.has_alias() assert d2.has_alias() # Both return an alias; the second multiplies the value by 10: e1 = TestFactory7(tag.alias, tag.pointer, 9) e2 = PythFactory7(tag.alias, tag.pointer, 10) assert e1.get() == 9 assert e2.get() == 200 assert e1.has_alias() assert e2.has_alias() f1 = TestFactory7(tag.shared_ptr, tag.base, 11) f2 = PythFactory7(tag.shared_ptr, tag.base, 12) assert f1.get() == 11 assert f2.get() == 112 assert not f1.has_alias() assert f2.has_alias() g1 = TestFactory7(tag.shared_ptr, tag.invalid_base, 13) assert g1.get() == 13 assert not g1.has_alias() with pytest.raises(TypeError) as excinfo: PythFactory7(tag.shared_ptr, tag.invalid_base, 14) assert (str(excinfo.value) == "pybind11::init(): construction failed: returned holder-wrapped instance is not an " "alias instance") assert [i.alive() for i in cstats] == [13, 7] assert ConstructorStats.detail_reg_inst() == n_inst + 13 del a1, a2, b1, d1, e1, e2 assert [i.alive() for i in cstats] == [7, 4] assert ConstructorStats.detail_reg_inst() == n_inst + 7 del b2, c1, c2, d2, f1, f2, g1 assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst assert [i.values() for i in cstats] == [ ["1", "2", "3", "4", "5", "6", "7", "8", "9", "100", "11", "12", "13", "14"], ["2", "4", "6", "8", "9", "100", "12"] ]
def test_init_factory_dual(): """Tests init factory functions with dual main/alias factory functions""" from pybind11_tests.factory_constructors import TestFactory7 cstats = [TestFactory7.get_cstats(), TestFactory7.get_alias_cstats()] cstats[0].alive() # force gc n_inst = ConstructorStats.detail_reg_inst() class PythFactory7(TestFactory7): def get(self): return 100 + TestFactory7.get(self) a1 = TestFactory7(1) a2 = PythFactory7(2) assert a1.get() == 1 assert a2.get() == 102 assert not a1.has_alias() assert a2.has_alias() b1 = TestFactory7(tag.pointer, 3) b2 = PythFactory7(tag.pointer, 4) assert b1.get() == 3 assert b2.get() == 104 assert not b1.has_alias() assert b2.has_alias() c1 = TestFactory7(tag.mixed, 5) c2 = PythFactory7(tag.mixed, 6) assert c1.get() == 5 assert c2.get() == 106 assert not c1.has_alias() assert c2.has_alias() d1 = TestFactory7(tag.base, tag.pointer, 7) d2 = PythFactory7(tag.base, tag.pointer, 8) assert d1.get() == 7 assert d2.get() == 108 assert not d1.has_alias() assert d2.has_alias() # Both return an alias; the second multiplies the value by 10: e1 = TestFactory7(tag.alias, tag.pointer, 9) e2 = PythFactory7(tag.alias, tag.pointer, 10) assert e1.get() == 9 assert e2.get() == 200 assert e1.has_alias() assert e2.has_alias() f1 = TestFactory7(tag.shared_ptr, tag.base, 11) f2 = PythFactory7(tag.shared_ptr, tag.base, 12) assert f1.get() == 11 assert f2.get() == 112 assert not f1.has_alias() assert f2.has_alias() g1 = TestFactory7(tag.shared_ptr, tag.invalid_base, 13) assert g1.get() == 13 assert not g1.has_alias() with pytest.raises(TypeError) as excinfo: PythFactory7(tag.shared_ptr, tag.invalid_base, 14) assert ( str(excinfo.value) == "pybind11::init(): construction failed: returned holder-wrapped instance is not an " "alias instance") assert [i.alive() for i in cstats] == [13, 7] assert ConstructorStats.detail_reg_inst() == n_inst + 13 del a1, a2, b1, d1, e1, e2 assert [i.alive() for i in cstats] == [7, 4] assert ConstructorStats.detail_reg_inst() == n_inst + 7 del b2, c1, c2, d2, f1, f2, g1 assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst assert [i.values() for i in cstats] == [[ "1", "2", "3", "4", "5", "6", "7", "8", "9", "100", "11", "12", "13", "14" ], ["2", "4", "6", "8", "9", "100", "12"]]
def test_init_factory_alias(): """Tests py::init_factory() wrapper with value conversions and alias types""" cstats = [m.TestFactory6.get_cstats(), m.TestFactory6.get_alias_cstats()] cstats[0].alive() # force gc n_inst = ConstructorStats.detail_reg_inst() a = m.TestFactory6(tag.base, 1) assert a.get() == 1 assert not a.has_alias() b = m.TestFactory6(tag.alias, "hi there") assert b.get() == 8 assert b.has_alias() c = m.TestFactory6(tag.alias, 3) assert c.get() == 3 assert c.has_alias() d = m.TestFactory6(tag.alias, tag.pointer, 4) assert d.get() == 4 assert d.has_alias() e = m.TestFactory6(tag.base, tag.pointer, 5) assert e.get() == 5 assert not e.has_alias() f = m.TestFactory6(tag.base, tag.alias, tag.pointer, 6) assert f.get() == 6 assert f.has_alias() assert ConstructorStats.detail_reg_inst() == n_inst + 6 assert [i.alive() for i in cstats] == [6, 4] del a, b, e assert [i.alive() for i in cstats] == [3, 3] assert ConstructorStats.detail_reg_inst() == n_inst + 3 del f, c, d assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst class MyTest(m.TestFactory6): def __init__(self, *args): m.TestFactory6.__init__(self, *args) def get(self): return -5 + m.TestFactory6.get(self) # Return Class by value, moved into new alias: z = MyTest(tag.base, 123) assert z.get() == 118 assert z.has_alias() # Return alias by value, moved into new alias: y = MyTest(tag.alias, "why hello!") assert y.get() == 5 assert y.has_alias() # Return Class by pointer, moved into new alias then original destroyed: x = MyTest(tag.base, tag.pointer, 47) assert x.get() == 42 assert x.has_alias() assert ConstructorStats.detail_reg_inst() == n_inst + 3 assert [i.alive() for i in cstats] == [3, 3] del x, y, z assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst assert [i.values() for i in cstats] == [ ["1", "8", "3", "4", "5", "6", "123", "10", "47"], ["hi there", "3", "4", "6", "move", "123", "why hello!", "move", "47"] ]