From 4a236bbd742e8e68fe150dc0fec78128204cf199 Mon Sep 17 00:00:00 2001 From: Yichen Yan Date: Sun, 23 May 2021 21:34:57 +0800 Subject: [PATCH 1/2] POC test for #2847 --- tests/pybind11_cross_module_tests.cpp | 8 ++++++++ tests/test_exceptions.cpp | 2 ++ tests/test_exceptions.h | 10 ++++++++++ tests/test_exceptions.py | 3 +++ 4 files changed, 23 insertions(+) create mode 100644 tests/test_exceptions.h diff --git a/tests/pybind11_cross_module_tests.cpp b/tests/pybind11_cross_module_tests.cpp index f705e31061..73c7b8c808 100644 --- a/tests/pybind11_cross_module_tests.cpp +++ b/tests/pybind11_cross_module_tests.cpp @@ -9,6 +9,7 @@ #include "pybind11_tests.h" #include "local_bindings.h" +#include "test_exceptions.h" #include #include @@ -30,6 +31,13 @@ PYBIND11_MODULE(pybind11_cross_module_tests, m) { m.def("throw_pybind_value_error", []() { throw py::value_error("pybind11 value error"); }); m.def("throw_pybind_type_error", []() { throw py::type_error("pybind11 type error"); }); m.def("throw_stop_iteration", []() { throw py::stop_iteration(); }); + py::register_exception_translator([](std::exception_ptr p) { + try { + if (p) std::rethrow_exception(p); + } catch (const tmp_e &e) { + PyErr_SetString(PyExc_KeyError, e.what()); + } + }); // test_local_bindings.py // Local to both: diff --git a/tests/test_exceptions.cpp b/tests/test_exceptions.cpp index e27c16dfef..2ebb747a60 100644 --- a/tests/test_exceptions.cpp +++ b/tests/test_exceptions.cpp @@ -7,6 +7,7 @@ BSD-style license that can be found in the LICENSE file. */ +#include "test_exceptions.h" #include "pybind11_tests.h" // A type that should be raised as an exception in Python @@ -228,4 +229,5 @@ TEST_SUBMODULE(exceptions, m) { // Test repr that cannot be displayed m.def("simple_bool_passthrough", [](bool x) {return x;}); + m.def("throw_", []() { throw tmp_e(); }); } diff --git a/tests/test_exceptions.h b/tests/test_exceptions.h new file mode 100644 index 0000000000..1aad71bad4 --- /dev/null +++ b/tests/test_exceptions.h @@ -0,0 +1,10 @@ +#pragma once +#include "pybind11_tests.h" +#include + +// shared exceptions for cross_module_tests + +class tmp_e : public std::runtime_error { +public: + explicit tmp_e() : std::runtime_error("") {} +}; diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index c6cb65299e..1656a4770e 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -43,6 +43,9 @@ def test_cross_module_exceptions(): with pytest.raises(StopIteration) as excinfo: cm.throw_stop_iteration() + with pytest.raises(KeyError) as excinfo: + m.throw_() + def test_python_call_in_catch(): d = {} From 42bc068c89c3f5b511eda30e6655db2fc95db8bb Mon Sep 17 00:00:00 2001 From: Yichen Yan Date: Sun, 23 May 2021 21:53:31 +0800 Subject: [PATCH 2/2] use `pybind11::builtin_exception` --- tests/test_exceptions.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_exceptions.h b/tests/test_exceptions.h index 1aad71bad4..27a80292f1 100644 --- a/tests/test_exceptions.h +++ b/tests/test_exceptions.h @@ -4,7 +4,9 @@ // shared exceptions for cross_module_tests -class tmp_e : public std::runtime_error { +class PYBIND11_EXPORT tmp_e : public pybind11::builtin_exception { public: - explicit tmp_e() : std::runtime_error("") {} + using builtin_exception::builtin_exception; + explicit tmp_e() : tmp_e("") {} + void set_error() const override { PyErr_SetString(PyExc_RuntimeError, what()); } };