From 0e489777ff919a70970823d40378ad16be1ee06e Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Sun, 11 Sep 2016 18:41:28 -0400 Subject: [PATCH] Added a test to detect invalid RTTI caching The current inheritance testing isn't sufficient to detect a cache failure; the test added here breaks PR #390, which caches the run-time-determined return type the first time a function is called, then reuses that cached type even though the run-time type could be different for a future call. --- tests/test_inheritance.cpp | 5 +++++ tests/test_inheritance.py | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/test_inheritance.cpp b/tests/test_inheritance.cpp index 798befffc..f75e9cff7 100644 --- a/tests/test_inheritance.cpp +++ b/tests/test_inheritance.cpp @@ -77,5 +77,10 @@ test_initializer inheritance([](py::module &m) { m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); }); m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); }); + m.def("return_class_n", [](int n) -> BaseClass* { + if (n == 1) return new DerivedClass1(); + if (n == 2) return new DerivedClass2(); + return new BaseClass(); + }); m.def("return_none", []() -> BaseClass* { return nullptr; }); }); diff --git a/tests/test_inheritance.py b/tests/test_inheritance.py index d4cea8253..d6997b09c 100644 --- a/tests/test_inheritance.py +++ b/tests/test_inheritance.py @@ -31,8 +31,16 @@ def test_inheritance(msg): def test_automatic_upcasting(): - from pybind11_tests import return_class_1, return_class_2, return_none + from pybind11_tests import return_class_1, return_class_2, return_class_n, return_none assert type(return_class_1()).__name__ == "DerivedClass1" assert type(return_class_2()).__name__ == "DerivedClass2" assert type(return_none()).__name__ == "NoneType" + # Repeat these a few times in a random order to ensure no invalid caching is applied + assert type(return_class_n(1)).__name__ == "DerivedClass1" + assert type(return_class_n(2)).__name__ == "DerivedClass2" + assert type(return_class_n(0)).__name__ == "BaseClass" + assert type(return_class_n(2)).__name__ == "DerivedClass2" + assert type(return_class_n(2)).__name__ == "DerivedClass2" + assert type(return_class_n(0)).__name__ == "BaseClass" + assert type(return_class_n(1)).__name__ == "DerivedClass1"