Add error_scope to py::class_::dealloc() to protect destructor calls (#2342)
Fixes issue #1878
diff --git a/tests/test_class.cpp b/tests/test_class.cpp
index 7edcdce..5369cb0 100644
--- a/tests/test_class.cpp
+++ b/tests/test_class.cpp
@@ -379,6 +379,17 @@
// test_non_final_final
struct IsNonFinalFinal {};
py::class_<IsNonFinalFinal>(m, "IsNonFinalFinal", py::is_final());
+
+ struct PyPrintDestructor {
+ PyPrintDestructor() {}
+ ~PyPrintDestructor() {
+ py::print("Print from destructor");
+ }
+ void throw_something() { throw std::runtime_error("error"); }
+ };
+ py::class_<PyPrintDestructor>(m, "PyPrintDestructor")
+ .def(py::init<>())
+ .def("throw_something", &PyPrintDestructor::throw_something);
}
template <int N> class BreaksBase { public:
diff --git a/tests/test_class.py b/tests/test_class.py
index c38a5e8..bbf8481 100644
--- a/tests/test_class.py
+++ b/tests/test_class.py
@@ -323,3 +323,9 @@
class PyNonFinalFinalChild(m.IsNonFinalFinal):
pass
assert str(exc_info.value).endswith("is not an acceptable base type")
+
+
+# https://github.com/pybind/pybind11/issues/1878
+def test_exception_rvalue_abort():
+ with pytest.raises(RuntimeError):
+ m.PyPrintDestructor().throw_something()