Add and document py::error_already_set::discard_as_unraisable()
To deal with exceptions that hit destructors or other noexcept functions.
Includes fixes to support Python 2.7 and extends documentation on
error handling.
@virtuald and @YannickJadoul both contributed to this PR.
diff --git a/tests/test_exceptions.cpp b/tests/test_exceptions.cpp
index 56cd9bc..372d0ae 100644
--- a/tests/test_exceptions.cpp
+++ b/tests/test_exceptions.cpp
@@ -65,6 +65,25 @@
py::dict d;
};
+
+
+struct PythonAlreadySetInDestructor {
+ PythonAlreadySetInDestructor(const py::str &s) : s(s) {}
+ ~PythonAlreadySetInDestructor() {
+ py::dict foo;
+ try {
+ // Assign to a py::object to force read access of nonexistent dict entry
+ py::object o = foo["bar"];
+ }
+ catch (py::error_already_set& ex) {
+ ex.discard_as_unraisable(s);
+ }
+ }
+
+ py::str s;
+};
+
+
TEST_SUBMODULE(exceptions, m) {
m.def("throw_std_exception", []() {
throw std::runtime_error("This exception was intentionally thrown.");
@@ -183,6 +202,11 @@
return false;
});
+ m.def("python_alreadyset_in_destructor", [](py::str s) {
+ PythonAlreadySetInDestructor alreadyset_in_destructor(s);
+ return true;
+ });
+
// test_nested_throws
m.def("try_catch", [m](py::object exc_type, py::function f, py::args args) {
try { f(*args); }