blob: 27b0222afebf1f548edc29e7f06ecc615b17fed6 [file] [log] [blame]
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02001import pytest
2from pybind11_tests import ConstructorStats
3
4
5def test_override(capture, msg):
6 from pybind11_tests import (ExampleVirt, runExampleVirt, runExampleVirtVirtual,
7 runExampleVirtBool)
8
9 class ExtendedExampleVirt(ExampleVirt):
10 def __init__(self, state):
11 super(ExtendedExampleVirt, self).__init__(state + 1)
12 self.data = "Hello world"
13
14 def run(self, value):
15 print('ExtendedExampleVirt::run(%i), calling parent..' % value)
16 return super(ExtendedExampleVirt, self).run(value + 1)
17
18 def run_bool(self):
19 print('ExtendedExampleVirt::run_bool()')
20 return False
21
22 def pure_virtual(self):
23 print('ExtendedExampleVirt::pure_virtual(): %s' % self.data)
24
25 ex12 = ExampleVirt(10)
26 with capture:
27 assert runExampleVirt(ex12, 20) == 30
28 assert capture == "Original implementation of ExampleVirt::run(state=10, value=20)"
29
30 with pytest.raises(RuntimeError) as excinfo:
31 runExampleVirtVirtual(ex12)
32 assert msg(excinfo.value) == 'Tried to call pure virtual function "ExampleVirt::pure_virtual"'
33
34 ex12p = ExtendedExampleVirt(10)
35 with capture:
36 assert runExampleVirt(ex12p, 20) == 32
37 assert capture == """
38 ExtendedExampleVirt::run(20), calling parent..
39 Original implementation of ExampleVirt::run(state=11, value=21)
40 """
41 with capture:
42 assert runExampleVirtBool(ex12p) is False
43 assert capture == "ExtendedExampleVirt::run_bool()"
44 with capture:
45 runExampleVirtVirtual(ex12p)
46 assert capture == "ExtendedExampleVirt::pure_virtual(): Hello world"
47
48 cstats = ConstructorStats.get(ExampleVirt)
49 assert cstats.alive() == 2
50 del ex12, ex12p
51 assert cstats.alive() == 0
52 assert cstats.values() == ['10', '11']
53 assert cstats.copy_constructions == 0
54 assert cstats.move_constructions >= 0
55
56
57def test_inheriting_repeat(capture):
58 from pybind11_tests import A_Repeat, B_Repeat, C_Repeat, D_Repeat, A_Tpl, B_Tpl, C_Tpl, D_Tpl
59
60 class VI_AR(A_Repeat):
61 def unlucky_number(self):
62 return 99
63
64 class VI_AT(A_Tpl):
65 def unlucky_number(self):
66 return 999
67
68 obj = VI_AR()
69 with capture:
70 obj.say_something(3)
71 assert capture == "hihihi"
72 assert obj.unlucky_number() == 99
73
74 obj = VI_AT()
75 with capture:
76 obj.say_something(3)
77 assert capture == "hihihi"
78 assert obj.unlucky_number() == 999
79
80 for obj in [B_Repeat(), B_Tpl()]:
81 with capture:
82 obj.say_something(3)
83 assert capture == "B says hi 3 times"
84 assert obj.unlucky_number() == 13
85 assert obj.lucky_number() == 7.0
86
87 for obj in [C_Repeat(), C_Tpl()]:
88 with capture:
89 obj.say_something(3)
90 assert capture == "B says hi 3 times"
91 assert obj.unlucky_number() == 4444
92 assert obj.lucky_number() == 888.0
93
94 class VI_CR(C_Repeat):
95 def lucky_number(self):
96 return C_Repeat.lucky_number(self) + 1.25
97
98 obj = VI_CR()
99 with capture:
100 obj.say_something(3)
101 assert capture == "B says hi 3 times"
102 assert obj.unlucky_number() == 4444
103 assert obj.lucky_number() == 889.25
104
105 class VI_CT(C_Tpl):
106 pass
107
108 obj = VI_CT()
109 with capture:
110 obj.say_something(3)
111 assert capture == "B says hi 3 times"
112 assert obj.unlucky_number() == 4444
113 assert obj.lucky_number() == 888.0
114
115 class VI_CCR(VI_CR):
116 def lucky_number(self):
117 return VI_CR.lucky_number(self) * 10
118
119 obj = VI_CCR()
120 with capture:
121 obj.say_something(3)
122 assert capture == "B says hi 3 times"
123 assert obj.unlucky_number() == 4444
124 assert obj.lucky_number() == 8892.5
125
126 class VI_CCT(VI_CT):
127 def lucky_number(self):
128 return VI_CT.lucky_number(self) * 1000
129
130 obj = VI_CCT()
131 with capture:
132 obj.say_something(3)
133 assert capture == "B says hi 3 times"
134 assert obj.unlucky_number() == 4444
135 assert obj.lucky_number() == 888000.0
136
137 class VI_DR(D_Repeat):
138 def unlucky_number(self):
139 return 123
140
141 def lucky_number(self):
142 return 42.0
143
144 for obj in [D_Repeat(), D_Tpl()]:
145 with capture:
146 obj.say_something(3)
147 assert capture == "B says hi 3 times"
148 assert obj.unlucky_number() == 4444
149 assert obj.lucky_number() == 888.0
150
151 obj = VI_DR()
152 with capture:
153 obj.say_something(3)
154 assert capture == "B says hi 3 times"
155 assert obj.unlucky_number() == 123
156 assert obj.lucky_number() == 42.0
157
158 class VI_DT(D_Tpl):
159 def say_something(self, times):
160 print("VI_DT says:" + (' quack' * times))
161
162 def unlucky_number(self):
163 return 1234
164
165 def lucky_number(self):
166 return -4.25
167
168 obj = VI_DT()
169 with capture:
170 obj.say_something(3)
171 assert capture == "VI_DT says: quack quack quack"
172 assert obj.unlucky_number() == 1234
173 assert obj.lucky_number() == -4.25
174
175
Dean Moldovan665e8802016-08-12 22:28:31 +0200176def test_move_support(capture):
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200177 from pybind11_tests import NCVirt, NonCopyable, Movable
178
179 class NCVirtExt(NCVirt):
180 def get_noncopyable(self, a, b):
181 # Constructs and returns a new instance:
182 nc = NonCopyable(a*a, b*b)
183 return nc
184
185 def get_movable(self, a, b):
186 # Return a referenced copy
187 self.movable = Movable(a, b)
188 return self.movable
189
190 class NCVirtExt2(NCVirt):
191 def get_noncopyable(self, a, b):
192 # Keep a reference: this is going to throw an exception
193 self.nc = NonCopyable(a, b)
194 return self.nc
195
196 def get_movable(self, a, b):
197 # Return a new instance without storing it
198 return Movable(a, b)
199
200 ncv1 = NCVirtExt()
201 with capture:
202 ncv1.print_nc(2, 3)
203 assert capture == "36"
204 with capture:
205 ncv1.print_movable(4, 5)
206 assert capture == "9"
207 ncv2 = NCVirtExt2()
208 with capture:
209 ncv2.print_movable(7, 7)
210 assert capture == "14"
211 # Don't check the exception message here because it differs under debug/non-debug mode
212 with pytest.raises(RuntimeError):
213 ncv2.print_nc(9, 9)
214
215 nc_stats = ConstructorStats.get(NonCopyable)
216 mv_stats = ConstructorStats.get(Movable)
217 assert nc_stats.alive() == 1
218 assert mv_stats.alive() == 1
219 del ncv1, ncv2
220 assert nc_stats.alive() == 0
221 assert mv_stats.alive() == 0
222 assert nc_stats.values() == ['4', '9', '9', '9']
223 assert mv_stats.values() == ['4', '5', '7', '7']
224 assert nc_stats.copy_constructions == 0
225 assert mv_stats.copy_constructions == 1
226 assert nc_stats.move_constructions >= 0
227 assert mv_stats.move_constructions >= 0