blob: 0e3230c5739360578a2d53eeaad002a3306ec950 [file] [log] [blame]
Henry Schreinerd8c7ee02020-07-20 13:35:21 -04001# -*- coding: utf-8 -*-
Wenzel Jakob1d1f81b2016-12-16 15:00:46 +01002import pytest
Jason Rhinelander391c7542017-07-25 16:47:36 -04003from pybind11_tests import call_policies as m
4from pybind11_tests import ConstructorStats
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02005
6
7def test_keep_alive_argument(capture):
Bruce Merry9d698f72017-06-24 14:58:42 +02008 n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02009 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040010 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020011 assert capture == "Allocating parent."
12 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040013 p.addChild(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +020014 assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020015 assert capture == """
16 Allocating child.
17 Releasing child.
18 """
19 with capture:
20 del p
Bruce Merry9d698f72017-06-24 14:58:42 +020021 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020022 assert capture == "Releasing parent."
23
24 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040025 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020026 assert capture == "Allocating parent."
27 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040028 p.addChildKeepAlive(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +020029 assert ConstructorStats.detail_reg_inst() == n_inst + 2
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020030 assert capture == "Allocating child."
31 with capture:
32 del p
Bruce Merry9d698f72017-06-24 14:58:42 +020033 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020034 assert capture == """
35 Releasing parent.
36 Releasing child.
37 """
38
39
40def test_keep_alive_return_value(capture):
Bruce Merry9d698f72017-06-24 14:58:42 +020041 n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020042 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040043 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020044 assert capture == "Allocating parent."
45 with capture:
46 p.returnChild()
Bruce Merry9d698f72017-06-24 14:58:42 +020047 assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020048 assert capture == """
49 Allocating child.
50 Releasing child.
51 """
52 with capture:
53 del p
Bruce Merry9d698f72017-06-24 14:58:42 +020054 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020055 assert capture == "Releasing parent."
56
57 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -040058 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020059 assert capture == "Allocating parent."
60 with capture:
61 p.returnChildKeepAlive()
Bruce Merry9d698f72017-06-24 14:58:42 +020062 assert ConstructorStats.detail_reg_inst() == n_inst + 2
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020063 assert capture == "Allocating child."
64 with capture:
65 del p
Bruce Merry9d698f72017-06-24 14:58:42 +020066 assert ConstructorStats.detail_reg_inst() == n_inst
67 assert capture == """
68 Releasing parent.
69 Releasing child.
70 """
71
72
73# https://bitbucket.org/pypy/pypy/issues/2447
74@pytest.unsupported_on_pypy
75def test_alive_gc(capture):
Bruce Merry9d698f72017-06-24 14:58:42 +020076 n_inst = ConstructorStats.detail_reg_inst()
Jason Rhinelander391c7542017-07-25 16:47:36 -040077 p = m.ParentGC()
78 p.addChildKeepAlive(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +020079 assert ConstructorStats.detail_reg_inst() == n_inst + 2
80 lst = [p]
81 lst.append(lst) # creates a circular reference
82 with capture:
83 del p, lst
84 assert ConstructorStats.detail_reg_inst() == n_inst
85 assert capture == """
86 Releasing parent.
87 Releasing child.
88 """
89
90
91def test_alive_gc_derived(capture):
Jason Rhinelander391c7542017-07-25 16:47:36 -040092 class Derived(m.Parent):
Bruce Merry9d698f72017-06-24 14:58:42 +020093 pass
94
95 n_inst = ConstructorStats.detail_reg_inst()
96 p = Derived()
Jason Rhinelander391c7542017-07-25 16:47:36 -040097 p.addChildKeepAlive(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +020098 assert ConstructorStats.detail_reg_inst() == n_inst + 2
99 lst = [p]
100 lst.append(lst) # creates a circular reference
101 with capture:
102 del p, lst
103 assert ConstructorStats.detail_reg_inst() == n_inst
104 assert capture == """
105 Releasing parent.
106 Releasing child.
107 """
108
109
110def test_alive_gc_multi_derived(capture):
Jason Rhinelander391c7542017-07-25 16:47:36 -0400111 class Derived(m.Parent, m.Child):
Jason Rhinelander353615f2017-07-25 00:53:23 -0400112 def __init__(self):
Jason Rhinelander391c7542017-07-25 16:47:36 -0400113 m.Parent.__init__(self)
114 m.Child.__init__(self)
Bruce Merry9d698f72017-06-24 14:58:42 +0200115
116 n_inst = ConstructorStats.detail_reg_inst()
117 p = Derived()
Jason Rhinelander391c7542017-07-25 16:47:36 -0400118 p.addChildKeepAlive(m.Child())
Bruce Merry9d698f72017-06-24 14:58:42 +0200119 # +3 rather than +2 because Derived corresponds to two registered instances
120 assert ConstructorStats.detail_reg_inst() == n_inst + 3
121 lst = [p]
122 lst.append(lst) # creates a circular reference
123 with capture:
124 del p, lst
125 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200126 assert capture == """
127 Releasing parent.
128 Releasing child.
Jason Rhinelander353615f2017-07-25 00:53:23 -0400129 Releasing child.
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200130 """
131
132
133def test_return_none(capture):
Bruce Merry9d698f72017-06-24 14:58:42 +0200134 n_inst = ConstructorStats.detail_reg_inst()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200135 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -0400136 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200137 assert capture == "Allocating parent."
138 with capture:
139 p.returnNullChildKeepAliveChild()
Bruce Merry9d698f72017-06-24 14:58:42 +0200140 assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200141 assert capture == ""
142 with capture:
143 del p
Bruce Merry9d698f72017-06-24 14:58:42 +0200144 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200145 assert capture == "Releasing parent."
146
147 with capture:
Jason Rhinelander391c7542017-07-25 16:47:36 -0400148 p = m.Parent()
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200149 assert capture == "Allocating parent."
150 with capture:
151 p.returnNullChildKeepAliveParent()
Bruce Merry9d698f72017-06-24 14:58:42 +0200152 assert ConstructorStats.detail_reg_inst() == n_inst + 1
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200153 assert capture == ""
154 with capture:
155 del p
Bruce Merry9d698f72017-06-24 14:58:42 +0200156 assert ConstructorStats.detail_reg_inst() == n_inst
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200157 assert capture == "Releasing parent."
Dean Moldovan1ac19032017-03-16 11:22:26 +0100158
159
Dean Moldovan7939f4b2017-09-04 13:49:19 +0200160def test_keep_alive_constructor(capture):
161 n_inst = ConstructorStats.detail_reg_inst()
162
163 with capture:
164 p = m.Parent(m.Child())
165 assert ConstructorStats.detail_reg_inst() == n_inst + 2
166 assert capture == """
167 Allocating child.
168 Allocating parent.
169 """
170 with capture:
171 del p
172 assert ConstructorStats.detail_reg_inst() == n_inst
173 assert capture == """
174 Releasing parent.
175 Releasing child.
176 """
177
178
Dean Moldovan1ac19032017-03-16 11:22:26 +0100179def test_call_guard():
Jason Rhinelander391c7542017-07-25 16:47:36 -0400180 assert m.unguarded_call() == "unguarded"
181 assert m.guarded_call() == "guarded"
Dean Moldovan1ac19032017-03-16 11:22:26 +0100182
Jason Rhinelander391c7542017-07-25 16:47:36 -0400183 assert m.multiple_guards_correct_order() == "guarded & guarded"
184 assert m.multiple_guards_wrong_order() == "unguarded & guarded"
Dean Moldovan1ac19032017-03-16 11:22:26 +0100185
Jason Rhinelander391c7542017-07-25 16:47:36 -0400186 if hasattr(m, "with_gil"):
187 assert m.with_gil() == "GIL held"
188 assert m.without_gil() == "GIL released"