5 m = pytest.importorskip(
"pybind11_tests.virtual_functions")
6 from pybind11_tests
import ConstructorStats
10 class ExtendedExampleVirt(m.ExampleVirt):
13 self.data =
"Hello world" 16 print(f
"ExtendedExampleVirt::run({value}), calling parent..")
17 return super().
run(value + 1)
20 print(
"ExtendedExampleVirt::run_bool()")
23 def get_string1(self):
26 def pure_virtual(self):
27 print(f
"ExtendedExampleVirt::pure_virtual(): {self.data}")
29 class ExtendedExampleVirt2(ExtendedExampleVirt):
33 def get_string2(self):
36 ex12 = m.ExampleVirt(10)
38 assert m.runExampleVirt(ex12, 20) == 30
42 Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2) 46 with pytest.raises(RuntimeError)
as excinfo:
47 m.runExampleVirtVirtual(ex12)
50 ==
'Tried to call pure virtual function "ExampleVirt::pure_virtual"' 53 ex12p = ExtendedExampleVirt(10)
55 assert m.runExampleVirt(ex12p, 20) == 32
59 ExtendedExampleVirt::run(20), calling parent.. 60 Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2) 64 assert m.runExampleVirtBool(ex12p)
is False 65 assert capture ==
"ExtendedExampleVirt::run_bool()" 67 m.runExampleVirtVirtual(ex12p)
68 assert capture ==
"ExtendedExampleVirt::pure_virtual(): Hello world" 70 ex12p2 = ExtendedExampleVirt2(15)
72 assert m.runExampleVirt(ex12p2, 50) == 68
76 ExtendedExampleVirt::run(50), calling parent.. 77 Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2) 82 assert cstats.alive() == 3
83 del ex12, ex12p, ex12p2
84 assert cstats.alive() == 0
85 assert cstats.values() == [
"10",
"11",
"17"]
86 assert cstats.copy_constructions == 0
87 assert cstats.move_constructions >= 0
91 """`A` only initializes its trampoline class when we inherit from it 93 If we just create and use an A instance directly, the trampoline initialization is 94 bypassed and we only initialize an A() instead (for performance reasons). 102 print(
"In python f()")
110 assert capture ==
"A.f()" 130 """`A2`, unlike the above, is configured to always initialize the alias 132 While the extra initialization and extra class layer has small virtual dispatch 133 performance penalty, it also allows us to do more things with the trampoline 134 class such as defining local variables and performing construction/destruction. 142 print(
"In python B2.f()")
187 @pytest.mark.xfail(
"env.PYPY")
189 not hasattr(m,
"NCVirt"), reason=
"NCVirt does not work on Intel/PGI/NVCC compilers" 192 class NCVirtExt(m.NCVirt):
193 def get_noncopyable(self, a, b):
195 nc = m.NonCopyable(a * a, b * b)
198 def get_movable(self, a, b):
200 self.movable = m.Movable(a, b)
203 class NCVirtExt2(m.NCVirt):
204 def get_noncopyable(self, a, b):
206 self.nc = m.NonCopyable(a, b)
209 def get_movable(self, a, b):
211 return m.Movable(a, b)
214 assert ncv1.print_nc(2, 3) ==
"36" 215 assert ncv1.print_movable(4, 5) ==
"9" 217 assert ncv2.print_movable(7, 7) ==
"14" 219 with pytest.raises(RuntimeError):
224 assert nc_stats.alive() == 1
225 assert mv_stats.alive() == 1
227 assert nc_stats.alive() == 0
228 assert mv_stats.alive() == 0
229 assert nc_stats.values() == [
"4",
"9",
"9",
"9"]
230 assert mv_stats.values() == [
"4",
"5",
"7",
"7"]
231 assert nc_stats.copy_constructions == 0
232 assert mv_stats.copy_constructions == 1
233 assert nc_stats.move_constructions >= 0
234 assert mv_stats.move_constructions >= 0
238 """#159: virtual function dispatch has problems with similar-named functions""" 240 class PyClass1(m.DispatchIssue):
244 class PyClass2(m.DispatchIssue):
246 with pytest.raises(RuntimeError)
as excinfo:
250 ==
'Tried to call pure virtual function "Base::dispatch"' 253 return m.dispatch_issue_go(PyClass1())
256 assert m.dispatch_issue_go(b) ==
"Yay.." 260 """#3357: Recursive dispatch fails to find python function override""" 267 class Adder(m.Adder):
268 def __call__(self, first, second, visitor):
272 (
lambda: visitor(Data(first.value + second.value)))()
274 class StoreResultVisitor:
278 def __call__(self, data):
279 self.result = data.value
281 store = StoreResultVisitor()
283 m.add2(Data(1), Data(2),
Adder(), store)
284 assert store.result == 3
288 m.add3(Data(1), Data(2), Data(3),
Adder(), store)
289 assert store.result == 6
293 """#392/397: overriding reference-returning functions""" 294 o = m.OverrideTest(
"asdf")
299 assert o.str_value() ==
"asdf" 301 assert o.A_value().value ==
"hi" 303 assert a.value ==
"hi" 305 assert a.value ==
"bye" 309 class AR(m.A_Repeat):
310 def unlucky_number(self):
314 def unlucky_number(self):
318 assert obj.say_something(3) ==
"hihihi" 319 assert obj.unlucky_number() == 99
320 assert obj.say_everything() ==
"hi 99" 323 assert obj.say_something(3) ==
"hihihi" 324 assert obj.unlucky_number() == 999
325 assert obj.say_everything() ==
"hi 999" 327 for obj
in [m.B_Repeat(), m.B_Tpl()]:
328 assert obj.say_something(3) ==
"B says hi 3 times" 329 assert obj.unlucky_number() == 13
330 assert obj.lucky_number() == 7.0
331 assert obj.say_everything() ==
"B says hi 1 times 13" 333 for obj
in [m.C_Repeat(), m.C_Tpl()]:
334 assert obj.say_something(3) ==
"B says hi 3 times" 335 assert obj.unlucky_number() == 4444
336 assert obj.lucky_number() == 888.0
337 assert obj.say_everything() ==
"B says hi 1 times 4444" 339 class CR(m.C_Repeat):
340 def lucky_number(self):
341 return m.C_Repeat.lucky_number(self) + 1.25
344 assert obj.say_something(3) ==
"B says hi 3 times" 345 assert obj.unlucky_number() == 4444
346 assert obj.lucky_number() == 889.25
347 assert obj.say_everything() ==
"B says hi 1 times 4444" 353 assert obj.say_something(3) ==
"B says hi 3 times" 354 assert obj.unlucky_number() == 4444
355 assert obj.lucky_number() == 888.0
356 assert obj.say_everything() ==
"B says hi 1 times 4444" 359 def lucky_number(self):
360 return CR.lucky_number(self) * 10
363 assert obj.say_something(3) ==
"B says hi 3 times" 364 assert obj.unlucky_number() == 4444
365 assert obj.lucky_number() == 8892.5
366 assert obj.say_everything() ==
"B says hi 1 times 4444" 369 def lucky_number(self):
370 return CT.lucky_number(self) * 1000
373 assert obj.say_something(3) ==
"B says hi 3 times" 374 assert obj.unlucky_number() == 4444
375 assert obj.lucky_number() == 888000.0
376 assert obj.say_everything() ==
"B says hi 1 times 4444" 378 class DR(m.D_Repeat):
379 def unlucky_number(self):
382 def lucky_number(self):
385 for obj
in [m.D_Repeat(), m.D_Tpl()]:
386 assert obj.say_something(3) ==
"B says hi 3 times" 387 assert obj.unlucky_number() == 4444
388 assert obj.lucky_number() == 888.0
389 assert obj.say_everything() ==
"B says hi 1 times 4444" 392 assert obj.say_something(3) ==
"B says hi 3 times" 393 assert obj.unlucky_number() == 123
394 assert obj.lucky_number() == 42.0
395 assert obj.say_everything() ==
"B says hi 1 times 123" 398 def say_something(self, times):
399 return "DT says:" + (
" quack" * times)
401 def unlucky_number(self):
404 def lucky_number(self):
408 assert obj.say_something(3) ==
"DT says: quack quack quack" 409 assert obj.unlucky_number() == 1234
410 assert obj.lucky_number() == -4.25
411 assert obj.say_everything() ==
"DT says: quack 1234" 414 def say_something(self, times):
415 return "DT2: " + (
"QUACK" * times)
417 def unlucky_number(self):
421 def say_something(self, times):
424 def unlucky_number(self):
427 def lucky_number(self):
431 assert obj.say_something(3) ==
"BTBTBT" 432 assert obj.unlucky_number() == -7
433 assert obj.lucky_number() == -1.375
434 assert obj.say_everything() ==
"BT -7" 440 m.test_gil_from_thread()
445 class Test(m.test_override_cache_helper):
452 class Test(m.test_override_cache_helper):
457 for _
in range(1500):
458 assert m.test_override_cache(
func()) == 42
459 assert m.test_override_cache(
func2()) == 0
def test_alias_delay_initialization1(capture)
bool hasattr(handle obj, handle name)
EIGEN_STRONG_INLINE Packet4f print(const Packet4f &a)
static ConstructorStats & get(std::type_index type)
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
def test_python_override()
def test_recursive_dispatch_issue(msg)
def test_alias_delay_initialization2(capture)
def test_dispatch_issue(msg)
Double_ range(const Point2_ &p, const Point2_ &q)
def test_inherited_virtuals()
def test_override(capture, msg)