File tree 3 files changed +24
-0
lines changed 3 files changed +24
-0
lines changed Original file line number Diff line number Diff line change @@ -1388,6 +1388,13 @@ class class_ : public detail::generic_type {
1388
1388
1389
1389
// / Deallocates an instance; via holder, if constructed; otherwise via operator delete.
1390
1390
static void dealloc (detail::value_and_holder &v_h) {
1391
+ // We could be deallocating because we are cleaning up after a Python exception.
1392
+ // If so, the Python error indicator will be set. We need to clear that before
1393
+ // running the destructor, in case the destructor code calls more Python.
1394
+ // If we don't, the Python API will exit with an exception, and pybind11 will
1395
+ // throw error_already_set from the C++ destructor which is forbidden and triggers
1396
+ // std::terminate().
1397
+ error_scope scope;
1391
1398
if (v_h.holder_constructed ()) {
1392
1399
v_h.holder <holder_type>().~holder_type ();
1393
1400
v_h.set_holder_constructed (false );
Original file line number Diff line number Diff line change @@ -379,6 +379,17 @@ TEST_SUBMODULE(class_, m) {
379
379
// test_non_final_final
380
380
struct IsNonFinalFinal {};
381
381
py::class_<IsNonFinalFinal>(m, " IsNonFinalFinal" , py::is_final ());
382
+
383
+ struct PyPrintDestructor {
384
+ PyPrintDestructor () {}
385
+ ~PyPrintDestructor () {
386
+ py::print (" Print from destructor" );
387
+ }
388
+ void throw_something () { throw std::runtime_error (" error" ); }
389
+ };
390
+ py::class_<PyPrintDestructor>(m, " PyPrintDestructor" )
391
+ .def (py::init<>())
392
+ .def (" throw_something" , &PyPrintDestructor::throw_something);
382
393
}
383
394
384
395
template <int N> class BreaksBase { public:
Original file line number Diff line number Diff line change @@ -323,3 +323,9 @@ def test_non_final_final():
323
323
class PyNonFinalFinalChild (m .IsNonFinalFinal ):
324
324
pass
325
325
assert str (exc_info .value ).endswith ("is not an acceptable base type" )
326
+
327
+
328
+ # https://github.com/pybind/pybind11/issues/1878
329
+ def test_exception_rvalue_abort ():
330
+ with pytest .raises (RuntimeError ):
331
+ m .PyPrintDestructor ().throw_something ()
You can’t perform that action at this time.
0 commit comments