|
1 | 1 | import pytest
|
| 2 | +import weakref |
2 | 3 |
|
3 | 4 | from pybind11_tests import class_ as m
|
4 | 5 | from pybind11_tests import UserType, ConstructorStats
|
@@ -289,3 +290,34 @@ def test_aligned():
|
289 | 290 | if hasattr(m, "Aligned"):
|
290 | 291 | p = m.Aligned().ptr()
|
291 | 292 | assert p % 1024 == 0
|
| 293 | + |
| 294 | + |
| 295 | +def test_1922(): |
| 296 | + # Test #1922 (drake#11424). |
| 297 | + # Define a derived class which *does not* overload the method. |
| 298 | + # WARNING: The reproduction of this failure may be platform-specific, and |
| 299 | + # seems to depend on the order of definition and/or the name of the classes |
| 300 | + # defined. For example, trying to place this and the C++ code in |
| 301 | + # `test_virtual_functions` makes `assert id_1 == id_2` below fail. |
| 302 | + class Child1(m.ExampleVirt2): pass |
| 303 | + |
| 304 | + id_1 = id(Child1) |
| 305 | + assert m.example_virt2_get_name(m.ExampleVirt2()) == "ExampleVirt2" |
| 306 | + assert m.example_virt2_get_name(Child1()) == "ExampleVirt2" |
| 307 | + |
| 308 | + # Now delete everything (and ensure it's deleted). |
| 309 | + wref = weakref.ref(Child1) |
| 310 | + del Child1 |
| 311 | + pytest.gc_collect() |
| 312 | + assert wref() == None |
| 313 | + |
| 314 | + # Define a derived class which *does* define an overload. |
| 315 | + class Child2(m.ExampleVirt2): |
| 316 | + def get_name(self): return "Child2" |
| 317 | + |
| 318 | + id_2 = id(Child2) |
| 319 | + assert id_1 == id_2 # This happens in CPython; not sure about PyPy. |
| 320 | + assert m.example_virt2_get_name(m.ExampleVirt2()) == "ExampleVirt2" |
| 321 | + # THIS WILL FAIL: This is using the cached `ExampleVirt2.get_name`, rather |
| 322 | + # than re-inspect the Python dictionary. |
| 323 | + assert m.example_virt2_get_name(Child2()) == "Child2" |
0 commit comments