`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 constru
(capture)
| 136 | |
| 137 | @pytest.mark.skipif("env.GRAALPY", reason="Cannot reliably trigger GC") |
| 138 | def test_alias_delay_initialization2(capture): |
| 139 | """`A2`, unlike the above, is configured to always initialize the alias |
| 140 | |
| 141 | While the extra initialization and extra class layer has small virtual dispatch |
| 142 | performance penalty, it also allows us to do more things with the trampoline |
| 143 | class such as defining local variables and performing construction/destruction. |
| 144 | """ |
| 145 | |
| 146 | class B2(m.A2): |
| 147 | def __init__(self): |
| 148 | super().__init__() |
| 149 | |
| 150 | def f(self): |
| 151 | print("In python B2.f()") |
| 152 | |
| 153 | # No python subclass version |
| 154 | with capture: |
| 155 | a2 = m.A2() |
| 156 | m.call_f(a2) |
| 157 | del a2 |
| 158 | pytest.gc_collect() |
| 159 | a3 = m.A2(1) |
| 160 | m.call_f(a3) |
| 161 | del a3 |
| 162 | pytest.gc_collect() |
| 163 | assert ( |
| 164 | capture |
| 165 | == """ |
| 166 | PyA2.PyA2() |
| 167 | PyA2.f() |
| 168 | A2.f() |
| 169 | PyA2.~PyA2() |
| 170 | PyA2.PyA2() |
| 171 | PyA2.f() |
| 172 | A2.f() |
| 173 | PyA2.~PyA2() |
| 174 | """ |
| 175 | ) |
| 176 | |
| 177 | # Python subclass version |
| 178 | with capture: |
| 179 | b2 = B2() |
| 180 | m.call_f(b2) |
| 181 | del b2 |
| 182 | pytest.gc_collect() |
| 183 | assert ( |
| 184 | capture |
| 185 | == """ |
| 186 | PyA2.PyA2() |
| 187 | PyA2.f() |
| 188 | In python B2.f() |
| 189 | PyA2.~PyA2() |
| 190 | """ |
| 191 | ) |
| 192 | |
| 193 | |
| 194 | # PyPy: Reference count > 1 causes call with noncopyable instance |