diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 5578c65160..6a89b73f1a 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -100,7 +100,7 @@ struct internals { std::unordered_set, override_hash> inactive_override_cache; type_map> direct_conversions; std::unordered_map> patients; - std::forward_list registered_exception_translators; + std::forward_list registered_exception_translators; std::unordered_map shared_data; // Custom data to be shared across extensions std::vector loader_patient_stack; // Used by `loader_life_support` std::forward_list static_strings; // Stores the std::strings backing detail::c_str() @@ -223,7 +223,7 @@ inline internals **&get_internals_pp() { return internals_pp; } -inline void translate_exception(std::exception_ptr p) { +inline void translate_exception(const std::exception_ptr &p) { try { if (p) std::rethrow_exception(p); } catch (error_already_set &e) { e.restore(); return; @@ -243,7 +243,7 @@ inline void translate_exception(std::exception_ptr p) { } #if !defined(__GLIBCXX__) -inline void translate_local_exception(std::exception_ptr p) { +inline void translate_local_exception(const std::exception_ptr &p) { try { if (p) std::rethrow_exception(p); } catch (error_already_set &e) { e.restore(); return; diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 616fa70255..8f1ede3faf 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -2000,10 +2000,13 @@ template void implicitly_convertible() pybind11_fail("implicitly_convertible: Unable to find type " + type_id()); } -template -void register_exception_translator(ExceptionTranslator&& translator) { - detail::get_internals().registered_exception_translators.push_front( - std::forward(translator)); +inline void register_exception_translator(void (*translator)(const std::exception_ptr &)) { + detail::get_internals().registered_exception_translators.push_front(translator); +} + +inline void register_exception_translator(void (*)(std::exception_ptr)) { + pybind11_fail("Please update your exception translator."); + // or change internals even more } /** @@ -2054,7 +2057,7 @@ exception ®ister_exception(handle scope, auto &ex = detail::get_exception_object(); if (!ex) ex = exception(scope, name, base); - register_exception_translator([](std::exception_ptr p) { + register_exception_translator([](const std::exception_ptr &p) { if (!p) return; try { std::rethrow_exception(p); diff --git a/tests/pybind11_cross_module_tests.cpp b/tests/pybind11_cross_module_tests.cpp index 27a349d231..ca6305223d 100644 --- a/tests/pybind11_cross_module_tests.cpp +++ b/tests/pybind11_cross_module_tests.cpp @@ -34,7 +34,7 @@ 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) { + py::register_exception_translator([](const std::exception_ptr &p) { try { if (p) std::rethrow_exception(p); } catch (const shared_exception &e) { diff --git a/tests/test_exceptions.cpp b/tests/test_exceptions.cpp index d34f1a94e1..a01f4e041d 100644 --- a/tests/test_exceptions.cpp +++ b/tests/test_exceptions.cpp @@ -101,7 +101,7 @@ TEST_SUBMODULE(exceptions, m) { // make a new custom exception and use it as a translation target static py::exception ex(m, "MyException"); - py::register_exception_translator([](std::exception_ptr p) { + py::register_exception_translator([](const std::exception_ptr &p) { try { if (p) std::rethrow_exception(p); } catch (const MyException &e) { @@ -113,7 +113,7 @@ TEST_SUBMODULE(exceptions, m) { // register new translator for MyException2 // no need to store anything here because this type will // never by visible from Python - py::register_exception_translator([](std::exception_ptr p) { + py::register_exception_translator([](const std::exception_ptr &p) { try { if (p) std::rethrow_exception(p); } catch (const MyException2 &e) { @@ -125,7 +125,7 @@ TEST_SUBMODULE(exceptions, m) { // register new translator for MyException4 // which will catch it and delegate to the previously registered // translator for MyException by throwing a new exception - py::register_exception_translator([](std::exception_ptr p) { + py::register_exception_translator([](const std::exception_ptr &p) { try { if (p) std::rethrow_exception(p); } catch (const MyException4 &e) {