From 02df6c01146f7470d37f7b9728d05d7154f7383f Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 12 May 2022 01:30:20 -0700 Subject: [PATCH] Normalize the exception only locally in error_string(). Python 3.6 & 3.7 test failures expected. This is meant for benchmarking, to determine if it is worth the trouble looking into the failures. --- include/pybind11/detail/type_caster_base.h | 17 +++++++++++------ include/pybind11/pytypes.h | 1 - 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index 01312f14e..ae8994945 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -477,16 +477,22 @@ error_string(PyObject *exc_type, PyObject *exc_value, PyObject *exc_trace) { "Internal error: pybind11::detail::error_string() called with exc_type == nullptr"); } - auto result = handle(exc_type).attr("__name__").cast(); + // Normalize the exception only locally (to avoid side-effects for our caller). + object exc_type_loc = reinterpret_borrow(exc_type); + object exc_value_loc = reinterpret_borrow(exc_value); + object exc_trace_loc = reinterpret_borrow(exc_trace); + PyErr_NormalizeException(&exc_type_loc.ptr(), &exc_value_loc.ptr(), &exc_trace_loc.ptr()); + + auto result = exc_type_loc.attr("__name__").cast(); result += ": "; - if (exc_value) { - result += (std::string) str(exc_value); + if (exc_value_loc) { + result += (std::string) str(exc_value_loc); } - if (exc_trace) { + if (exc_trace_loc) { #if !defined(PYPY_VERSION) - auto *tb = reinterpret_cast(exc_trace); + auto *tb = reinterpret_cast(exc_trace_loc.ptr()); // Get the deepest trace possible. while (tb->tb_next) { @@ -529,7 +535,6 @@ error_string(PyObject *exc_type, PyObject *exc_value, PyObject *exc_trace) { PYBIND11_NOINLINE std::string error_string() { error_scope scope; // Fetch error state. - PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace); return error_string(scope.type, scope.value, scope.trace); } diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 847a7b34a..45b771ebe 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -395,7 +395,6 @@ public: "Python error indicator not set."); } PyErr_Fetch(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr()); - PyErr_NormalizeException(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr()); } error_already_set(const error_already_set &) = default;