blob: 5d55d5ecec57f114d1913ff0c493fc210020c1b7 [file] [log] [blame]
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02001import pytest
Wenzel Jakob1ffce742016-08-25 01:43:33 +02002import pybind11_tests
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02003from pybind11_tests import ConstructorStats
4
5
6def test_override(capture, msg):
7 from pybind11_tests import (ExampleVirt, runExampleVirt, runExampleVirtVirtual,
8 runExampleVirtBool)
9
10 class ExtendedExampleVirt(ExampleVirt):
11 def __init__(self, state):
12 super(ExtendedExampleVirt, self).__init__(state + 1)
13 self.data = "Hello world"
14
15 def run(self, value):
16 print('ExtendedExampleVirt::run(%i), calling parent..' % value)
17 return super(ExtendedExampleVirt, self).run(value + 1)
18
19 def run_bool(self):
20 print('ExtendedExampleVirt::run_bool()')
21 return False
22
Jason Rhinelander7dfb9322016-09-08 14:49:43 -040023 def get_string1(self):
24 return "override1"
25
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020026 def pure_virtual(self):
27 print('ExtendedExampleVirt::pure_virtual(): %s' % self.data)
28
Jason Rhinelander7dfb9322016-09-08 14:49:43 -040029 class ExtendedExampleVirt2(ExtendedExampleVirt):
30 def __init__(self, state):
31 super(ExtendedExampleVirt2, self).__init__(state + 1)
32
33 def get_string2(self):
34 return "override2"
35
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020036 ex12 = ExampleVirt(10)
37 with capture:
38 assert runExampleVirt(ex12, 20) == 30
Jason Rhinelander7dfb9322016-09-08 14:49:43 -040039 assert capture == "Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2)"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020040
41 with pytest.raises(RuntimeError) as excinfo:
42 runExampleVirtVirtual(ex12)
43 assert msg(excinfo.value) == 'Tried to call pure virtual function "ExampleVirt::pure_virtual"'
44
45 ex12p = ExtendedExampleVirt(10)
46 with capture:
47 assert runExampleVirt(ex12p, 20) == 32
48 assert capture == """
49 ExtendedExampleVirt::run(20), calling parent..
Jason Rhinelander7dfb9322016-09-08 14:49:43 -040050 Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2)
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020051 """
52 with capture:
53 assert runExampleVirtBool(ex12p) is False
54 assert capture == "ExtendedExampleVirt::run_bool()"
55 with capture:
56 runExampleVirtVirtual(ex12p)
57 assert capture == "ExtendedExampleVirt::pure_virtual(): Hello world"
58
Jason Rhinelander7dfb9322016-09-08 14:49:43 -040059 ex12p2 = ExtendedExampleVirt2(15)
60 with capture:
61 assert runExampleVirt(ex12p2, 50) == 68
62 assert capture == """
63 ExtendedExampleVirt::run(50), calling parent..
64 Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2)
65 """
66
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020067 cstats = ConstructorStats.get(ExampleVirt)
Jason Rhinelander7dfb9322016-09-08 14:49:43 -040068 assert cstats.alive() == 3
69 del ex12, ex12p, ex12p2
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020070 assert cstats.alive() == 0
Jason Rhinelander7dfb9322016-09-08 14:49:43 -040071 assert cstats.values() == ['10', '11', '17']
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020072 assert cstats.copy_constructions == 0
73 assert cstats.move_constructions >= 0
74
75
Dean Moldovan99dbdc12016-08-19 13:45:36 +020076def test_inheriting_repeat():
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020077 from pybind11_tests import A_Repeat, B_Repeat, C_Repeat, D_Repeat, A_Tpl, B_Tpl, C_Tpl, D_Tpl
78
79 class VI_AR(A_Repeat):
80 def unlucky_number(self):
81 return 99
82
83 class VI_AT(A_Tpl):
84 def unlucky_number(self):
85 return 999
86
87 obj = VI_AR()
Dean Moldovan99dbdc12016-08-19 13:45:36 +020088 assert obj.say_something(3) == "hihihi"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020089 assert obj.unlucky_number() == 99
Jason Rhinelander20978262016-08-29 18:16:46 -040090 assert obj.say_everything() == "hi 99"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020091
92 obj = VI_AT()
Dean Moldovan99dbdc12016-08-19 13:45:36 +020093 assert obj.say_something(3) == "hihihi"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020094 assert obj.unlucky_number() == 999
Jason Rhinelander20978262016-08-29 18:16:46 -040095 assert obj.say_everything() == "hi 999"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020096
97 for obj in [B_Repeat(), B_Tpl()]:
Dean Moldovan99dbdc12016-08-19 13:45:36 +020098 assert obj.say_something(3) == "B says hi 3 times"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +020099 assert obj.unlucky_number() == 13
100 assert obj.lucky_number() == 7.0
Jason Rhinelander20978262016-08-29 18:16:46 -0400101 assert obj.say_everything() == "B says hi 1 times 13"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200102
103 for obj in [C_Repeat(), C_Tpl()]:
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200104 assert obj.say_something(3) == "B says hi 3 times"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200105 assert obj.unlucky_number() == 4444
106 assert obj.lucky_number() == 888.0
Jason Rhinelander20978262016-08-29 18:16:46 -0400107 assert obj.say_everything() == "B says hi 1 times 4444"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200108
109 class VI_CR(C_Repeat):
110 def lucky_number(self):
111 return C_Repeat.lucky_number(self) + 1.25
112
113 obj = VI_CR()
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200114 assert obj.say_something(3) == "B says hi 3 times"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200115 assert obj.unlucky_number() == 4444
116 assert obj.lucky_number() == 889.25
Jason Rhinelander20978262016-08-29 18:16:46 -0400117 assert obj.say_everything() == "B says hi 1 times 4444"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200118
119 class VI_CT(C_Tpl):
120 pass
121
122 obj = VI_CT()
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200123 assert obj.say_something(3) == "B says hi 3 times"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200124 assert obj.unlucky_number() == 4444
125 assert obj.lucky_number() == 888.0
Jason Rhinelander20978262016-08-29 18:16:46 -0400126 assert obj.say_everything() == "B says hi 1 times 4444"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200127
128 class VI_CCR(VI_CR):
129 def lucky_number(self):
130 return VI_CR.lucky_number(self) * 10
131
132 obj = VI_CCR()
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200133 assert obj.say_something(3) == "B says hi 3 times"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200134 assert obj.unlucky_number() == 4444
135 assert obj.lucky_number() == 8892.5
Jason Rhinelander20978262016-08-29 18:16:46 -0400136 assert obj.say_everything() == "B says hi 1 times 4444"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200137
138 class VI_CCT(VI_CT):
139 def lucky_number(self):
140 return VI_CT.lucky_number(self) * 1000
141
142 obj = VI_CCT()
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200143 assert obj.say_something(3) == "B says hi 3 times"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200144 assert obj.unlucky_number() == 4444
145 assert obj.lucky_number() == 888000.0
Jason Rhinelander20978262016-08-29 18:16:46 -0400146 assert obj.say_everything() == "B says hi 1 times 4444"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200147
148 class VI_DR(D_Repeat):
149 def unlucky_number(self):
150 return 123
151
152 def lucky_number(self):
153 return 42.0
154
155 for obj in [D_Repeat(), D_Tpl()]:
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200156 assert obj.say_something(3) == "B says hi 3 times"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200157 assert obj.unlucky_number() == 4444
158 assert obj.lucky_number() == 888.0
Jason Rhinelander20978262016-08-29 18:16:46 -0400159 assert obj.say_everything() == "B says hi 1 times 4444"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200160
161 obj = VI_DR()
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200162 assert obj.say_something(3) == "B says hi 3 times"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200163 assert obj.unlucky_number() == 123
164 assert obj.lucky_number() == 42.0
Jason Rhinelander20978262016-08-29 18:16:46 -0400165 assert obj.say_everything() == "B says hi 1 times 123"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200166
167 class VI_DT(D_Tpl):
168 def say_something(self, times):
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200169 return "VI_DT says:" + (' quack' * times)
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200170
171 def unlucky_number(self):
172 return 1234
173
174 def lucky_number(self):
175 return -4.25
176
177 obj = VI_DT()
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200178 assert obj.say_something(3) == "VI_DT says: quack quack quack"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200179 assert obj.unlucky_number() == 1234
180 assert obj.lucky_number() == -4.25
Jason Rhinelander20978262016-08-29 18:16:46 -0400181 assert obj.say_everything() == "VI_DT says: quack 1234"
182
183 class VI_DT2(VI_DT):
184 def say_something(self, times):
185 return "VI_DT2: " + ('QUACK' * times)
186
187 def unlucky_number(self):
188 return -3
189
190 class VI_BT(B_Tpl):
191 def say_something(self, times):
192 return "VI_BT" * times
193 def unlucky_number(self):
194 return -7
195 def lucky_number(self):
196 return -1.375
197
198 obj = VI_BT()
199 assert obj.say_something(3) == "VI_BTVI_BTVI_BT"
200 assert obj.unlucky_number() == -7
201 assert obj.lucky_number() == -1.375
202 assert obj.say_everything() == "VI_BT -7"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200203
Wenzel Jakob69b62462016-08-25 02:20:35 +0200204@pytest.mark.skipif(not hasattr(pybind11_tests, 'NCVirt'),
205 reason="NCVirt test broken on ICPC")
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200206def test_move_support():
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200207 from pybind11_tests import NCVirt, NonCopyable, Movable
208
209 class NCVirtExt(NCVirt):
210 def get_noncopyable(self, a, b):
211 # Constructs and returns a new instance:
Wenzel Jakob69b62462016-08-25 02:20:35 +0200212 nc = NonCopyable(a * a, b * b)
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200213 return nc
214
215 def get_movable(self, a, b):
216 # Return a referenced copy
217 self.movable = Movable(a, b)
218 return self.movable
219
220 class NCVirtExt2(NCVirt):
221 def get_noncopyable(self, a, b):
222 # Keep a reference: this is going to throw an exception
223 self.nc = NonCopyable(a, b)
224 return self.nc
225
226 def get_movable(self, a, b):
227 # Return a new instance without storing it
228 return Movable(a, b)
229
230 ncv1 = NCVirtExt()
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200231 assert ncv1.print_nc(2, 3) == "36"
232 assert ncv1.print_movable(4, 5) == "9"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200233 ncv2 = NCVirtExt2()
Dean Moldovan99dbdc12016-08-19 13:45:36 +0200234 assert ncv2.print_movable(7, 7) == "14"
Dean Moldovana0c1ccf2016-08-12 13:50:00 +0200235 # Don't check the exception message here because it differs under debug/non-debug mode
236 with pytest.raises(RuntimeError):
237 ncv2.print_nc(9, 9)
238
239 nc_stats = ConstructorStats.get(NonCopyable)
240 mv_stats = ConstructorStats.get(Movable)
241 assert nc_stats.alive() == 1
242 assert mv_stats.alive() == 1
243 del ncv1, ncv2
244 assert nc_stats.alive() == 0
245 assert mv_stats.alive() == 0
246 assert nc_stats.values() == ['4', '9', '9', '9']
247 assert mv_stats.values() == ['4', '5', '7', '7']
248 assert nc_stats.copy_constructions == 0
249 assert mv_stats.copy_constructions == 1
250 assert nc_stats.move_constructions >= 0
251 assert mv_stats.move_constructions >= 0