112391Sjason@lowepower.comimport pytest
212391Sjason@lowepower.comfrom pybind11_tests import call_policies as m
312391Sjason@lowepower.comfrom pybind11_tests import ConstructorStats
412391Sjason@lowepower.com
512391Sjason@lowepower.com
612391Sjason@lowepower.comdef test_keep_alive_argument(capture):
712391Sjason@lowepower.com    n_inst = ConstructorStats.detail_reg_inst()
812391Sjason@lowepower.com    with capture:
912391Sjason@lowepower.com        p = m.Parent()
1012391Sjason@lowepower.com    assert capture == "Allocating parent."
1112391Sjason@lowepower.com    with capture:
1212391Sjason@lowepower.com        p.addChild(m.Child())
1312391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst + 1
1412391Sjason@lowepower.com    assert capture == """
1512391Sjason@lowepower.com        Allocating child.
1612391Sjason@lowepower.com        Releasing child.
1712391Sjason@lowepower.com    """
1812391Sjason@lowepower.com    with capture:
1912391Sjason@lowepower.com        del p
2012391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
2112391Sjason@lowepower.com    assert capture == "Releasing parent."
2212391Sjason@lowepower.com
2312391Sjason@lowepower.com    with capture:
2412391Sjason@lowepower.com        p = m.Parent()
2512391Sjason@lowepower.com    assert capture == "Allocating parent."
2612391Sjason@lowepower.com    with capture:
2712391Sjason@lowepower.com        p.addChildKeepAlive(m.Child())
2812391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst + 2
2912391Sjason@lowepower.com    assert capture == "Allocating child."
3012391Sjason@lowepower.com    with capture:
3112391Sjason@lowepower.com        del p
3212391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
3312391Sjason@lowepower.com    assert capture == """
3412391Sjason@lowepower.com        Releasing parent.
3512391Sjason@lowepower.com        Releasing child.
3612391Sjason@lowepower.com    """
3712391Sjason@lowepower.com
3812391Sjason@lowepower.com
3912391Sjason@lowepower.comdef test_keep_alive_return_value(capture):
4012391Sjason@lowepower.com    n_inst = ConstructorStats.detail_reg_inst()
4112391Sjason@lowepower.com    with capture:
4212391Sjason@lowepower.com        p = m.Parent()
4312391Sjason@lowepower.com    assert capture == "Allocating parent."
4412391Sjason@lowepower.com    with capture:
4512391Sjason@lowepower.com        p.returnChild()
4612391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst + 1
4712391Sjason@lowepower.com    assert capture == """
4812391Sjason@lowepower.com        Allocating child.
4912391Sjason@lowepower.com        Releasing child.
5012391Sjason@lowepower.com    """
5112391Sjason@lowepower.com    with capture:
5212391Sjason@lowepower.com        del p
5312391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
5412391Sjason@lowepower.com    assert capture == "Releasing parent."
5512391Sjason@lowepower.com
5612391Sjason@lowepower.com    with capture:
5712391Sjason@lowepower.com        p = m.Parent()
5812391Sjason@lowepower.com    assert capture == "Allocating parent."
5912391Sjason@lowepower.com    with capture:
6012391Sjason@lowepower.com        p.returnChildKeepAlive()
6112391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst + 2
6212391Sjason@lowepower.com    assert capture == "Allocating child."
6312391Sjason@lowepower.com    with capture:
6412391Sjason@lowepower.com        del p
6512391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
6612391Sjason@lowepower.com    assert capture == """
6712391Sjason@lowepower.com        Releasing parent.
6812391Sjason@lowepower.com        Releasing child.
6912391Sjason@lowepower.com    """
7012391Sjason@lowepower.com
7112391Sjason@lowepower.com
7212391Sjason@lowepower.com# https://bitbucket.org/pypy/pypy/issues/2447
7312391Sjason@lowepower.com@pytest.unsupported_on_pypy
7412391Sjason@lowepower.comdef test_alive_gc(capture):
7512391Sjason@lowepower.com    n_inst = ConstructorStats.detail_reg_inst()
7612391Sjason@lowepower.com    p = m.ParentGC()
7712391Sjason@lowepower.com    p.addChildKeepAlive(m.Child())
7812391Sjason@lowepower.com    assert ConstructorStats.detail_reg_inst() == n_inst + 2
7912391Sjason@lowepower.com    lst = [p]
8012391Sjason@lowepower.com    lst.append(lst)   # creates a circular reference
8112391Sjason@lowepower.com    with capture:
8212391Sjason@lowepower.com        del p, lst
8312391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
8412391Sjason@lowepower.com    assert capture == """
8512391Sjason@lowepower.com        Releasing parent.
8612391Sjason@lowepower.com        Releasing child.
8712391Sjason@lowepower.com    """
8812391Sjason@lowepower.com
8912391Sjason@lowepower.com
9012391Sjason@lowepower.comdef test_alive_gc_derived(capture):
9112391Sjason@lowepower.com    class Derived(m.Parent):
9212391Sjason@lowepower.com        pass
9312391Sjason@lowepower.com
9412391Sjason@lowepower.com    n_inst = ConstructorStats.detail_reg_inst()
9512391Sjason@lowepower.com    p = Derived()
9612391Sjason@lowepower.com    p.addChildKeepAlive(m.Child())
9712391Sjason@lowepower.com    assert ConstructorStats.detail_reg_inst() == n_inst + 2
9812391Sjason@lowepower.com    lst = [p]
9912391Sjason@lowepower.com    lst.append(lst)   # creates a circular reference
10012391Sjason@lowepower.com    with capture:
10112391Sjason@lowepower.com        del p, lst
10212391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
10312391Sjason@lowepower.com    assert capture == """
10412391Sjason@lowepower.com        Releasing parent.
10512391Sjason@lowepower.com        Releasing child.
10612391Sjason@lowepower.com    """
10712391Sjason@lowepower.com
10812391Sjason@lowepower.com
10912391Sjason@lowepower.comdef test_alive_gc_multi_derived(capture):
11012391Sjason@lowepower.com    class Derived(m.Parent, m.Child):
11112391Sjason@lowepower.com        def __init__(self):
11212391Sjason@lowepower.com            m.Parent.__init__(self)
11312391Sjason@lowepower.com            m.Child.__init__(self)
11412391Sjason@lowepower.com
11512391Sjason@lowepower.com    n_inst = ConstructorStats.detail_reg_inst()
11612391Sjason@lowepower.com    p = Derived()
11712391Sjason@lowepower.com    p.addChildKeepAlive(m.Child())
11812391Sjason@lowepower.com    # +3 rather than +2 because Derived corresponds to two registered instances
11912391Sjason@lowepower.com    assert ConstructorStats.detail_reg_inst() == n_inst + 3
12012391Sjason@lowepower.com    lst = [p]
12112391Sjason@lowepower.com    lst.append(lst)   # creates a circular reference
12212391Sjason@lowepower.com    with capture:
12312391Sjason@lowepower.com        del p, lst
12412391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
12512391Sjason@lowepower.com    assert capture == """
12612391Sjason@lowepower.com        Releasing parent.
12712391Sjason@lowepower.com        Releasing child.
12812391Sjason@lowepower.com        Releasing child.
12912391Sjason@lowepower.com    """
13012391Sjason@lowepower.com
13112391Sjason@lowepower.com
13212391Sjason@lowepower.comdef test_return_none(capture):
13312391Sjason@lowepower.com    n_inst = ConstructorStats.detail_reg_inst()
13412391Sjason@lowepower.com    with capture:
13512391Sjason@lowepower.com        p = m.Parent()
13612391Sjason@lowepower.com    assert capture == "Allocating parent."
13712391Sjason@lowepower.com    with capture:
13812391Sjason@lowepower.com        p.returnNullChildKeepAliveChild()
13912391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst + 1
14012391Sjason@lowepower.com    assert capture == ""
14112391Sjason@lowepower.com    with capture:
14212391Sjason@lowepower.com        del p
14312391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
14412391Sjason@lowepower.com    assert capture == "Releasing parent."
14512391Sjason@lowepower.com
14612391Sjason@lowepower.com    with capture:
14712391Sjason@lowepower.com        p = m.Parent()
14812391Sjason@lowepower.com    assert capture == "Allocating parent."
14912391Sjason@lowepower.com    with capture:
15012391Sjason@lowepower.com        p.returnNullChildKeepAliveParent()
15112391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst + 1
15212391Sjason@lowepower.com    assert capture == ""
15312391Sjason@lowepower.com    with capture:
15412391Sjason@lowepower.com        del p
15512391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
15612391Sjason@lowepower.com    assert capture == "Releasing parent."
15712391Sjason@lowepower.com
15812391Sjason@lowepower.com
15912391Sjason@lowepower.comdef test_keep_alive_constructor(capture):
16012391Sjason@lowepower.com    n_inst = ConstructorStats.detail_reg_inst()
16112391Sjason@lowepower.com
16212391Sjason@lowepower.com    with capture:
16312391Sjason@lowepower.com        p = m.Parent(m.Child())
16412391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst + 2
16512391Sjason@lowepower.com    assert capture == """
16612391Sjason@lowepower.com        Allocating child.
16712391Sjason@lowepower.com        Allocating parent.
16812391Sjason@lowepower.com    """
16912391Sjason@lowepower.com    with capture:
17012391Sjason@lowepower.com        del p
17112391Sjason@lowepower.com        assert ConstructorStats.detail_reg_inst() == n_inst
17212391Sjason@lowepower.com    assert capture == """
17312391Sjason@lowepower.com        Releasing parent.
17412391Sjason@lowepower.com        Releasing child.
17512391Sjason@lowepower.com    """
17612391Sjason@lowepower.com
17712391Sjason@lowepower.com
17812391Sjason@lowepower.comdef test_call_guard():
17912391Sjason@lowepower.com    assert m.unguarded_call() == "unguarded"
18012391Sjason@lowepower.com    assert m.guarded_call() == "guarded"
18112391Sjason@lowepower.com
18212391Sjason@lowepower.com    assert m.multiple_guards_correct_order() == "guarded & guarded"
18312391Sjason@lowepower.com    assert m.multiple_guards_wrong_order() == "unguarded & guarded"
18412391Sjason@lowepower.com
18512391Sjason@lowepower.com    if hasattr(m, "with_gil"):
18612391Sjason@lowepower.com        assert m.with_gil() == "GIL held"
18712391Sjason@lowepower.com        assert m.without_gil() == "GIL released"
188