test_call_policies.py 5.22 KB
Newer Older
1
# -*- coding: utf-8 -*-
Wenzel Jakob's avatar
Wenzel Jakob committed
2
import pytest
3
4
from pybind11_tests import call_policies as m
from pybind11_tests import ConstructorStats
Dean Moldovan's avatar
Dean Moldovan committed
5
6
7


def test_keep_alive_argument(capture):
8
    n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovan's avatar
Dean Moldovan committed
9
    with capture:
10
        p = m.Parent()
Dean Moldovan's avatar
Dean Moldovan committed
11
12
    assert capture == "Allocating parent."
    with capture:
13
        p.addChild(m.Child())
14
        assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovan's avatar
Dean Moldovan committed
15
16
17
18
19
20
    assert capture == """
        Allocating child.
        Releasing child.
    """
    with capture:
        del p
21
        assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovan's avatar
Dean Moldovan committed
22
23
24
    assert capture == "Releasing parent."

    with capture:
25
        p = m.Parent()
Dean Moldovan's avatar
Dean Moldovan committed
26
27
    assert capture == "Allocating parent."
    with capture:
28
        p.addChildKeepAlive(m.Child())
29
        assert ConstructorStats.detail_reg_inst() == n_inst + 2
Dean Moldovan's avatar
Dean Moldovan committed
30
31
32
    assert capture == "Allocating child."
    with capture:
        del p
33
        assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovan's avatar
Dean Moldovan committed
34
35
36
37
38
39
40
    assert capture == """
        Releasing parent.
        Releasing child.
    """


def test_keep_alive_return_value(capture):
41
    n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovan's avatar
Dean Moldovan committed
42
    with capture:
43
        p = m.Parent()
Dean Moldovan's avatar
Dean Moldovan committed
44
45
46
    assert capture == "Allocating parent."
    with capture:
        p.returnChild()
47
        assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovan's avatar
Dean Moldovan committed
48
49
50
51
52
53
    assert capture == """
        Allocating child.
        Releasing child.
    """
    with capture:
        del p
54
        assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovan's avatar
Dean Moldovan committed
55
56
57
    assert capture == "Releasing parent."

    with capture:
58
        p = m.Parent()
Dean Moldovan's avatar
Dean Moldovan committed
59
60
61
    assert capture == "Allocating parent."
    with capture:
        p.returnChildKeepAlive()
62
        assert ConstructorStats.detail_reg_inst() == n_inst + 2
Dean Moldovan's avatar
Dean Moldovan committed
63
64
65
    assert capture == "Allocating child."
    with capture:
        del p
66
67
68
69
70
71
72
73
74
75
76
        assert ConstructorStats.detail_reg_inst() == n_inst
    assert capture == """
        Releasing parent.
        Releasing child.
    """


# https://bitbucket.org/pypy/pypy/issues/2447
@pytest.unsupported_on_pypy
def test_alive_gc(capture):
    n_inst = ConstructorStats.detail_reg_inst()
77
78
    p = m.ParentGC()
    p.addChildKeepAlive(m.Child())
79
80
81
82
83
84
85
86
87
88
89
90
91
    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_derived(capture):
92
    class Derived(m.Parent):
93
94
95
96
        pass

    n_inst = ConstructorStats.detail_reg_inst()
    p = Derived()
97
    p.addChildKeepAlive(m.Child())
98
99
100
101
102
103
104
105
106
107
108
109
110
    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):
111
    class Derived(m.Parent, m.Child):
112
        def __init__(self):
113
114
            m.Parent.__init__(self)
            m.Child.__init__(self)
115
116
117

    n_inst = ConstructorStats.detail_reg_inst()
    p = Derived()
118
    p.addChildKeepAlive(m.Child())
119
120
121
122
123
124
125
    # +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
Dean Moldovan's avatar
Dean Moldovan committed
126
127
128
    assert capture == """
        Releasing parent.
        Releasing child.
129
        Releasing child.
Dean Moldovan's avatar
Dean Moldovan committed
130
131
132
133
    """


def test_return_none(capture):
134
    n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovan's avatar
Dean Moldovan committed
135
    with capture:
136
        p = m.Parent()
Dean Moldovan's avatar
Dean Moldovan committed
137
138
139
    assert capture == "Allocating parent."
    with capture:
        p.returnNullChildKeepAliveChild()
140
        assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovan's avatar
Dean Moldovan committed
141
142
143
    assert capture == ""
    with capture:
        del p
144
        assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovan's avatar
Dean Moldovan committed
145
146
147
    assert capture == "Releasing parent."

    with capture:
148
        p = m.Parent()
Dean Moldovan's avatar
Dean Moldovan committed
149
150
151
    assert capture == "Allocating parent."
    with capture:
        p.returnNullChildKeepAliveParent()
152
        assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovan's avatar
Dean Moldovan committed
153
154
155
    assert capture == ""
    with capture:
        del p
156
        assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovan's avatar
Dean Moldovan committed
157
    assert capture == "Releasing parent."
Dean Moldovan's avatar
Dean Moldovan committed
158
159


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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 == """
        Releasing parent.
        Releasing child.
    """


Dean Moldovan's avatar
Dean Moldovan committed
179
def test_call_guard():
180
181
    assert m.unguarded_call() == "unguarded"
    assert m.guarded_call() == "guarded"
Dean Moldovan's avatar
Dean Moldovan committed
182

183
184
    assert m.multiple_guards_correct_order() == "guarded & guarded"
    assert m.multiple_guards_wrong_order() == "unguarded & guarded"
Dean Moldovan's avatar
Dean Moldovan committed
185

186
187
188
    if hasattr(m, "with_gil"):
        assert m.with_gil() == "GIL held"
        assert m.without_gil() == "GIL released"