Putting back the two eager PyErr_NormalizeException() calls.

This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-05-11 23:20:30 -07:00
parent 90b2453cbd
commit dded0243a4
2 changed files with 14 additions and 13 deletions

View File

@ -471,24 +471,22 @@ PYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp)
}
PYBIND11_NOINLINE std::string
error_string(PyObject **exc_type, PyObject **exc_value, PyObject **exc_trace) {
if (*exc_type == nullptr) {
error_string(PyObject *exc_type, PyObject *exc_value, PyObject *exc_trace) {
if (exc_type == nullptr) {
pybind11_fail(
"Internal error: pybind11::detail::error_string() called with exc_type == nullptr");
}
PyErr_NormalizeException(exc_type, exc_value, exc_trace);
auto result = handle(*exc_type).attr("__name__").cast<std::string>();
auto result = handle(exc_type).attr("__name__").cast<std::string>();
result += ": ";
if (*exc_value) {
result += (std::string) str(*exc_value);
if (exc_value) {
result += (std::string) str(exc_value);
}
if (*exc_trace) {
if (exc_trace) {
#if !defined(PYPY_VERSION)
auto *tb = reinterpret_cast<PyTracebackObject *>(*exc_trace);
auto *tb = reinterpret_cast<PyTracebackObject *>(exc_trace);
// Get the deepest trace possible.
while (tb->tb_next) {
@ -531,7 +529,8 @@ error_string(PyObject **exc_type, PyObject **exc_value, PyObject **exc_trace) {
PYBIND11_NOINLINE std::string error_string() {
error_scope scope; // Fetch error state.
return error_string(&scope.type, &scope.value, &scope.trace);
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
return error_string(scope.type, scope.value, scope.trace);
}
PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_info *type) {

View File

@ -364,7 +364,7 @@ T reinterpret_steal(handle h) {
PYBIND11_NAMESPACE_BEGIN(detail)
std::string error_string();
std::string error_string(PyObject **, PyObject **, PyObject **);
std::string error_string(PyObject *, PyObject *, PyObject *);
inline const char *obj_class_name(PyObject *obj) {
if (Py_TYPE(obj) == &PyType_Type) {
@ -396,6 +396,7 @@ public:
PyErr_SetString(PyExc_RuntimeError, m_lazy_what.c_str());
}
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;
@ -409,7 +410,7 @@ public:
const char *what() const noexcept override {
if (m_lazy_what.empty()) {
try {
m_lazy_what = detail::error_string(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());
m_lazy_what = detail::error_string(m_type.ptr(), m_value.ptr(), m_trace.ptr());
// Negate the if condition to test the catch(...) block below.
if (m_lazy_what.empty()) {
throw std::runtime_error(
@ -461,7 +462,8 @@ public:
// if already set).
void restore() {
// As long as this type is copyable, there is no point in releasing m_type, m_value,
// m_trace.
// m_trace, but simply holding on the the references makes it possible to produce
// what() even after restore().
PyErr_Restore(m_type.inc_ref().ptr(), m_value.inc_ref().ptr(), m_trace.inc_ref().ptr());
}