test_alias_initialization.py 1.86 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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()
    """