blob: 6c60f817475099c629cd35f7daffa0332a9c4927 [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
159def test_call_guard():
Jason Rhinelander391c7542017-07-25 16:47:36 -0400160 assert m.unguarded_call() == "unguarded"
161 assert m.guarded_call() == "guarded"
Dean Moldovan1ac19032017-03-16 11:22:26 +0100162
Jason Rhinelander391c7542017-07-25 16:47:36 -0400163 assert m.multiple_guards_correct_order() == "guarded & guarded"
164 assert m.multiple_guards_wrong_order() == "unguarded & guarded"
Dean Moldovan1ac19032017-03-16 11:22:26 +0100165
Jason Rhinelander391c7542017-07-25 16:47:36 -0400166 if hasattr(m, "with_gil"):
167 assert m.with_gil() == "GIL held"
168 assert m.without_gil() == "GIL released"