Skip to content

Commit

Permalink
Add unittest checking drake#11424
Browse files Browse the repository at this point in the history
Remove id check for newer result
  • Loading branch information
EricCousineau-TRI committed Jan 22, 2021
1 parent 7e991aa commit 8624889
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
18 changes: 18 additions & 0 deletions tests/test_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,24 @@ TEST_SUBMODULE(class_, m) {
py::class_<OtherDuplicateNested>(gt, "OtherDuplicateNested");
py::class_<OtherDuplicateNested>(gt, "YetAnotherDuplicateNested");
});

// Test drake#11424.
class ExampleVirt2 {
public:
virtual ~ExampleVirt2() {}
virtual std::string get_name() const { return "ExampleVirt2"; }
};
class PyExampleVirt2 : public ExampleVirt2 {
public:
std::string get_name() const override {
PYBIND11_OVERLOAD(std::string, ExampleVirt2, get_name, );
}
};
py::class_<ExampleVirt2, PyExampleVirt2>(m, "ExampleVirt2")
.def(py::init())
.def("get_name", &ExampleVirt2::get_name);
m.def("example_virt2_get_name",
[](const ExampleVirt2& obj) { return obj.get_name(); });
}

template <int N> class BreaksBase { public:
Expand Down
31 changes: 31 additions & 0 deletions tests/test_class.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import pytest
import weakref

import env # noqa: F401

Expand Down Expand Up @@ -464,3 +465,33 @@ class ClassScope:
m.register_duplicate_nested_class_type(ClassScope)
expected = 'generic_type: type "YetAnotherDuplicateNested" is already registered!'
assert str(exc_info.value) == expected


def test_drake_11424():
# Define a derived class which *does not* overload the method.
# WARNING: The reproduction of this failure may be platform-specific, and
# seems to depend on the order of definition and/or the name of the classes
# defined. For example, trying to place this and the C++ code in
# `test_virtual_functions` makes `assert id_1 == id_2` below fail.
class Child1(m.ExampleVirt2): pass

id_1 = id(Child1)
assert m.example_virt2_get_name(m.ExampleVirt2()) == "ExampleVirt2"
assert m.example_virt2_get_name(Child1()) == "ExampleVirt2"

# Now delete everything (and ensure it's deleted).
wref = weakref.ref(Child1)
del Child1
pytest.gc_collect()
assert wref() == None

# Define a derived class which *does* define an overload.
class Child2(m.ExampleVirt2):
def get_name(self): return "Child2"

id_2 = id(Child2)
# assert id_1 == id_2 # This happens in CPython; not sure about PyPy.
assert m.example_virt2_get_name(m.ExampleVirt2()) == "ExampleVirt2"
# THIS WILL FAIL: This is using the cached `ExampleVirt2.get_name`, rather
# than re-inspect the Python dictionary.
assert m.example_virt2_get_name(Child2()) == "Child2"

0 comments on commit 8624889

Please sign in to comment.