blob: 7c835599c2d736440243c1834f00a01f03ec5f28 [file] [log] [blame]
Wenzel Jakob1d1f81b2016-12-16 15:00:46 +01001import pytest
Jason Rhinelander391c7542017-07-25 16:47:36 -04002from pybind11_tests import call_policies as m
3from pybind11_tests import ConstructorStats
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02004
5
6def test_keep_alive_argument(capture):
Bruce Merry9d698f72017-06-24 14:58:42 +02007 n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02008 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -04009 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020010 assert capture == "Allocating parent."
11 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040012 p.addChild(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +020013 assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020014 assert capture == """
15 Allocating child.
16 Releasing child.
17 """
18 with capture:
19 del p
Bruce Merry9d698f72017-06-24 14:58:42 +020020 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020021 assert capture == "Releasing parent."
22
23 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040024 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020025 assert capture == "Allocating parent."
26 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040027 p.addChildKeepAlive(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +020028 assert ConstructorStats.detail_reg_inst() == n_inst + 2
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020029 assert capture == "Allocating child."
30 with capture:
31 del p
Bruce Merry9d698f72017-06-24 14:58:42 +020032 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020033 assert capture == """
34 Releasing parent.
35 Releasing child.
36 """
37
38
39def test_keep_alive_return_value(capture):
Bruce Merry9d698f72017-06-24 14:58:42 +020040 n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020041 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040042 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020043 assert capture == "Allocating parent."
44 with capture:
45 p.returnChild()
Bruce Merry9d698f72017-06-24 14:58:42 +020046 assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020047 assert capture == """
48 Allocating child.
49 Releasing child.
50 """
51 with capture:
52 del p
Bruce Merry9d698f72017-06-24 14:58:42 +020053 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020054 assert capture == "Releasing parent."
55
56 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040057 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020058 assert capture == "Allocating parent."
59 with capture:
60 p.returnChildKeepAlive()
Bruce Merry9d698f72017-06-24 14:58:42 +020061 assert ConstructorStats.detail_reg_inst() == n_inst + 2
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020062 assert capture == "Allocating child."
63 with capture:
64 del p
Bruce Merry9d698f72017-06-24 14:58:42 +020065 assert ConstructorStats.detail_reg_inst() == n_inst
66 assert capture == """
67 Releasing parent.
68 Releasing child.
69 """
70
71
72# https://bitbucket.org/pypy/pypy/issues/2447
73@pytest.unsupported_on_pypy
74def test_alive_gc(capture):
Bruce Merry9d698f72017-06-24 14:58:42 +020075 n_inst = ConstructorStats.detail_reg_inst()
Jason Rhinelander391c7542017-07-25 16:47:36 -040076 p = m.ParentGC()
77 p.addChildKeepAlive(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +020078 assert ConstructorStats.detail_reg_inst() == n_inst + 2
79 lst = [p]
80 lst.append(lst) # creates a circular reference
81 with capture:
82 del p, lst
83 assert ConstructorStats.detail_reg_inst() == n_inst
84 assert capture == """
85 Releasing parent.
86 Releasing child.
87 """
88
89
90def test_alive_gc_derived(capture):
Jason Rhinelander391c7542017-07-25 16:47:36 -040091 class Derived(m.Parent):
Bruce Merry9d698f72017-06-24 14:58:42 +020092 pass
93
94 n_inst = ConstructorStats.detail_reg_inst()
95 p = Derived()
Jason Rhinelander391c7542017-07-25 16:47:36 -040096 p.addChildKeepAlive(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +020097 assert ConstructorStats.detail_reg_inst() == n_inst + 2
98 lst = [p]
99 lst.append(lst) # creates a circular reference
100 with capture:
101 del p, lst
102 assert ConstructorStats.detail_reg_inst() == n_inst
103 assert capture == """
104 Releasing parent.
105 Releasing child.
106 """
107
108
109def test_alive_gc_multi_derived(capture):
Jason Rhinelander391c7542017-07-25 16:47:36 -0400110 class Derived(m.Parent, m.Child):
Jason Rhinelander353615f2017-07-25 00:53:23 -0400111 def __init__(self):
Jason Rhinelander391c7542017-07-25 16:47:36 -0400112 m.Parent.__init__(self)
113 m.Child.__init__(self)
Bruce Merry9d698f72017-06-24 14:58:42 +0200114
115 n_inst = ConstructorStats.detail_reg_inst()
116 p = Derived()
Jason Rhinelander391c7542017-07-25 16:47:36 -0400117 p.addChildKeepAlive(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +0200118 # +3 rather than +2 because Derived corresponds to two registered instances
119 assert ConstructorStats.detail_reg_inst() == n_inst + 3
120 lst = [p]
121 lst.append(lst) # creates a circular reference
122 with capture:
123 del p, lst
124 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200125 assert capture == """
126 Releasing parent.
127 Releasing child.
Jason Rhinelander353615f2017-07-25 00:53:23 -0400128 Releasing child.
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200129 """
130
131
132def test_return_none(capture):
Bruce Merry9d698f72017-06-24 14:58:42 +0200133 n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200134 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -0400135 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200136 assert capture == "Allocating parent."
137 with capture:
138 p.returnNullChildKeepAliveChild()
Bruce Merry9d698f72017-06-24 14:58:42 +0200139 assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200140 assert capture == ""
141 with capture:
142 del p
Bruce Merry9d698f72017-06-24 14:58:42 +0200143 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200144 assert capture == "Releasing parent."
145
146 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -0400147 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200148 assert capture == "Allocating parent."
149 with capture:
150 p.returnNullChildKeepAliveParent()
Bruce Merry9d698f72017-06-24 14:58:42 +0200151 assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200152 assert capture == ""
153 with capture:
154 del p
Bruce Merry9d698f72017-06-24 14:58:42 +0200155 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200156 assert capture == "Releasing parent."
Dean Moldovan1ac19032017-03-16 11:22:26 +0100157
158
Dean Moldovan7939f4b2017-09-04 13:49:19 +0200159def test_keep_alive_constructor(capture):
160 n_inst = ConstructorStats.detail_reg_inst()
161
162 with capture:
163 p = m.Parent(m.Child())
164 assert ConstructorStats.detail_reg_inst() == n_inst + 2
165 assert capture == """
166 Allocating child.
167 Allocating parent.
168 """
169 with capture:
170 del p
171 assert ConstructorStats.detail_reg_inst() == n_inst
172 assert capture == """
173 Releasing parent.
174 Releasing child.
175 """
176
177
Dean Moldovan1ac19032017-03-16 11:22:26 +0100178def test_call_guard():
Jason Rhinelander391c7542017-07-25 16:47:36 -0400179 assert m.unguarded_call() == "unguarded"
180 assert m.guarded_call() == "guarded"
Dean Moldovan1ac19032017-03-16 11:22:26 +0100181
Jason Rhinelander391c7542017-07-25 16:47:36 -0400182 assert m.multiple_guards_correct_order() == "guarded & guarded"
183 assert m.multiple_guards_wrong_order() == "unguarded & guarded"
Dean Moldovan1ac19032017-03-16 11:22:26 +0100184
Jason Rhinelander391c7542017-07-25 16:47:36 -0400185 if hasattr(m, "with_gil"):
186 assert m.with_gil() == "GIL held"
187 assert m.without_gil() == "GIL released"