pybind11/tests/test_alias_initialization.py

81 lines
1.9 KiB
Python
Raw Normal View History

import pytest
import gc
def test_alias_delay_initialization(capture, msg):
# A only initializes its trampoline class when we inherit from it; if we
# just create and use an A instance directly, the trampoline initialization
# is bypassed and we only initialize an A() instead (for performance
# reasons)
from pybind11_tests import A, call_f
class B(A):
def __init__(self):
super(B, self).__init__()
def f(self):
print("In python f()")
# C++ version
with capture:
a = A()
call_f(a)
del a
gc.collect()
assert capture == "A.f()"
# Python version
with capture:
b = B()
call_f(b)
del b
gc.collect()
assert capture == """
PyA.PyA()
PyA.f()
In python f()
PyA.~PyA()
"""
def test_alias_delay_initialization(capture, msg):
from pybind11_tests import A2, call_f
# A2, unlike the above, is configured to always initialize the alias; while
# the extra initialization and extra class layer has small virtual dispatch
# performance penalty, it also allows us to do more things with the
# trampoline class such as defining local variables and performing
# construction/destruction.
class B2(A2):
def __init__(self):
super(B2, self).__init__()
def f(self):
print("In python B2.f()")
# No python subclass version
with capture:
a2 = A2()
call_f(a2)
del a2
gc.collect()
assert capture == """
PyA2.PyA2()
PyA2.f()
A2.f()
PyA2.~PyA2()
"""
# Python subclass version
with capture:
b2 = B2()
call_f(b2)
del b2
gc.collect()
assert capture == """
PyA2.PyA2()
PyA2.f()
In python B2.f()
PyA2.~PyA2()
"""