6 m = pytest.importorskip(
"pybind11_tests.virtual_functions")
7 from pybind11_tests
import ConstructorStats
11 class ExtendedExampleVirt(m.ExampleVirt):
12 def __init__(self, state):
13 super(ExtendedExampleVirt, self).__init__(state + 1)
14 self.data =
"Hello world" 17 print(
'ExtendedExampleVirt::run(%i), calling parent..' % value)
18 return super(ExtendedExampleVirt, self).
run(value + 1)
21 print(
'ExtendedExampleVirt::run_bool()')
24 def get_string1(self):
27 def pure_virtual(self):
28 print(
'ExtendedExampleVirt::pure_virtual(): %s' % self.data)
30 class ExtendedExampleVirt2(ExtendedExampleVirt):
31 def __init__(self, state):
32 super(ExtendedExampleVirt2, self).__init__(state + 1)
34 def get_string2(self):
37 ex12 = m.ExampleVirt(10)
39 assert m.runExampleVirt(ex12, 20) == 30
41 Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2) 44 with pytest.raises(RuntimeError)
as excinfo:
45 m.runExampleVirtVirtual(ex12)
46 assert msg(excinfo.value) ==
'Tried to call pure virtual function "ExampleVirt::pure_virtual"' 48 ex12p = ExtendedExampleVirt(10)
50 assert m.runExampleVirt(ex12p, 20) == 32
52 ExtendedExampleVirt::run(20), calling parent.. 53 Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2) 56 assert m.runExampleVirtBool(ex12p)
is False 57 assert capture ==
"ExtendedExampleVirt::run_bool()" 59 m.runExampleVirtVirtual(ex12p)
60 assert capture ==
"ExtendedExampleVirt::pure_virtual(): Hello world" 62 ex12p2 = ExtendedExampleVirt2(15)
64 assert m.runExampleVirt(ex12p2, 50) == 68
66 ExtendedExampleVirt::run(50), calling parent.. 67 Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2) 71 assert cstats.alive() == 3
72 del ex12, ex12p, ex12p2
73 assert cstats.alive() == 0
74 assert cstats.values() == [
'10',
'11',
'17']
75 assert cstats.copy_constructions == 0
76 assert cstats.move_constructions >= 0
80 """`A` only initializes its trampoline class when we inherit from it 82 If we just create and use an A instance directly, the trampoline initialization is 83 bypassed and we only initialize an A() instead (for performance reasons). 87 super(B, self).__init__()
90 print(
"In python f()")
98 assert capture ==
"A.f()" 106 assert capture ==
""" 115 """`A2`, unlike the above, is configured to always initialize the alias 117 While the extra initialization and extra class layer has small virtual dispatch 118 performance penalty, it also allows us to do more things with the trampoline 119 class such as defining local variables and performing construction/destruction. 123 super(B2, self).__init__()
126 print(
"In python B2.f()")
138 assert capture ==
""" 155 assert capture ==
""" 165 @pytest.mark.xfail(
"env.PYPY")
166 @pytest.mark.skipif(
not hasattr(m,
"NCVirt"), reason=
"NCVirt test broken on ICPC")
168 class NCVirtExt(m.NCVirt):
169 def get_noncopyable(self, a, b):
171 nc = m.NonCopyable(a * a, b * b)
174 def get_movable(self, a, b):
176 self.movable = m.Movable(a, b)
179 class NCVirtExt2(m.NCVirt):
180 def get_noncopyable(self, a, b):
182 self.nc = m.NonCopyable(a, b)
185 def get_movable(self, a, b):
187 return m.Movable(a, b)
190 assert ncv1.print_nc(2, 3) ==
"36" 191 assert ncv1.print_movable(4, 5) ==
"9" 193 assert ncv2.print_movable(7, 7) ==
"14" 195 with pytest.raises(RuntimeError):
200 assert nc_stats.alive() == 1
201 assert mv_stats.alive() == 1
203 assert nc_stats.alive() == 0
204 assert mv_stats.alive() == 0
205 assert nc_stats.values() == [
'4',
'9',
'9',
'9']
206 assert mv_stats.values() == [
'4',
'5',
'7',
'7']
207 assert nc_stats.copy_constructions == 0
208 assert mv_stats.copy_constructions == 1
209 assert nc_stats.move_constructions >= 0
210 assert mv_stats.move_constructions >= 0
214 """#159: virtual function dispatch has problems with similar-named functions""" 215 class PyClass1(m.DispatchIssue):
219 class PyClass2(m.DispatchIssue):
221 with pytest.raises(RuntimeError)
as excinfo:
222 super(PyClass2, self).dispatch()
223 assert msg(excinfo.value) ==
'Tried to call pure virtual function "Base::dispatch"' 226 return m.dispatch_issue_go(p)
229 assert m.dispatch_issue_go(b) ==
"Yay.." 233 """#392/397: overriding reference-returning functions""" 234 o = m.OverrideTest(
"asdf")
239 assert o.str_value() ==
"asdf" 241 assert o.A_value().value ==
"hi" 243 assert a.value ==
"hi" 245 assert a.value ==
"bye" 249 class AR(m.A_Repeat):
250 def unlucky_number(self):
254 def unlucky_number(self):
258 assert obj.say_something(3) ==
"hihihi" 259 assert obj.unlucky_number() == 99
260 assert obj.say_everything() ==
"hi 99" 263 assert obj.say_something(3) ==
"hihihi" 264 assert obj.unlucky_number() == 999
265 assert obj.say_everything() ==
"hi 999" 267 for obj
in [m.B_Repeat(), m.B_Tpl()]:
268 assert obj.say_something(3) ==
"B says hi 3 times" 269 assert obj.unlucky_number() == 13
270 assert obj.lucky_number() == 7.0
271 assert obj.say_everything() ==
"B says hi 1 times 13" 273 for obj
in [m.C_Repeat(), m.C_Tpl()]:
274 assert obj.say_something(3) ==
"B says hi 3 times" 275 assert obj.unlucky_number() == 4444
276 assert obj.lucky_number() == 888.0
277 assert obj.say_everything() ==
"B says hi 1 times 4444" 279 class CR(m.C_Repeat):
280 def lucky_number(self):
281 return m.C_Repeat.lucky_number(self) + 1.25
284 assert obj.say_something(3) ==
"B says hi 3 times" 285 assert obj.unlucky_number() == 4444
286 assert obj.lucky_number() == 889.25
287 assert obj.say_everything() ==
"B says hi 1 times 4444" 293 assert obj.say_something(3) ==
"B says hi 3 times" 294 assert obj.unlucky_number() == 4444
295 assert obj.lucky_number() == 888.0
296 assert obj.say_everything() ==
"B says hi 1 times 4444" 299 def lucky_number(self):
300 return CR.lucky_number(self) * 10
303 assert obj.say_something(3) ==
"B says hi 3 times" 304 assert obj.unlucky_number() == 4444
305 assert obj.lucky_number() == 8892.5
306 assert obj.say_everything() ==
"B says hi 1 times 4444" 309 def lucky_number(self):
310 return CT.lucky_number(self) * 1000
313 assert obj.say_something(3) ==
"B says hi 3 times" 314 assert obj.unlucky_number() == 4444
315 assert obj.lucky_number() == 888000.0
316 assert obj.say_everything() ==
"B says hi 1 times 4444" 318 class DR(m.D_Repeat):
319 def unlucky_number(self):
322 def lucky_number(self):
325 for obj
in [m.D_Repeat(), m.D_Tpl()]:
326 assert obj.say_something(3) ==
"B says hi 3 times" 327 assert obj.unlucky_number() == 4444
328 assert obj.lucky_number() == 888.0
329 assert obj.say_everything() ==
"B says hi 1 times 4444" 332 assert obj.say_something(3) ==
"B says hi 3 times" 333 assert obj.unlucky_number() == 123
334 assert obj.lucky_number() == 42.0
335 assert obj.say_everything() ==
"B says hi 1 times 123" 338 def say_something(self, times):
339 return "DT says:" + (
' quack' * times)
341 def unlucky_number(self):
344 def lucky_number(self):
348 assert obj.say_something(3) ==
"DT says: quack quack quack" 349 assert obj.unlucky_number() == 1234
350 assert obj.lucky_number() == -4.25
351 assert obj.say_everything() ==
"DT says: quack 1234" 354 def say_something(self, times):
355 return "DT2: " + (
'QUACK' * times)
357 def unlucky_number(self):
361 def say_something(self, times):
364 def unlucky_number(self):
367 def lucky_number(self):
371 assert obj.say_something(3) ==
"BTBTBT" 372 assert obj.unlucky_number() == -7
373 assert obj.lucky_number() == -1.375
374 assert obj.say_everything() ==
"BT -7" 380 m.test_gil_from_thread()
void print(const Matrix &A, const string &s, ostream &stream)
def test_alias_delay_initialization1(capture)
bool hasattr(handle obj, handle name)
static ConstructorStats & get(std::type_index type)
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
def test_alias_delay_initialization2(capture)
def test_dispatch_issue(msg)
def test_inherited_virtuals()
def test_override(capture, msg)
void run(Expr &expr, Dev &dev)