mirror of
https://github.com/pybind/pybind11.git
synced 2024-12-02 18:07:12 +00:00
Cosmit following @YannickJadoul's comments
Note that detail::error_string() no longer calls PyException_SetTraceback as it is unncessary for pretty-printing the exception.
This commit is contained in:
parent
c935b73ba5
commit
b48bc720e0
@ -403,40 +403,31 @@ PYBIND11_NOINLINE inline bool isinstance_generic(handle obj, const std::type_inf
|
||||
return isinstance(obj, type);
|
||||
}
|
||||
|
||||
PYBIND11_NOINLINE inline std::string error_string(PyObject* type, PyObject* value, PyObject *trace) {
|
||||
if (!type && !value && !trace) {
|
||||
PYBIND11_NOINLINE inline std::string error_string(PyObject *type, PyObject *value, PyObject *trace) {
|
||||
if (!type) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred");
|
||||
return "Unknown internal error occurred";
|
||||
}
|
||||
|
||||
// TODO(superbobry): is it safe to assume that exception has been
|
||||
// normalized by the caller?
|
||||
std::string errorString;
|
||||
if (type) {
|
||||
errorString += handle(type).attr("__name__").cast<std::string>();
|
||||
errorString += ": ";
|
||||
}
|
||||
if (value)
|
||||
errorString += str(value).cast<std::string>();
|
||||
std::string result = handle(type).attr("__name__").cast<std::string>();
|
||||
result += ": ";
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
if (trace)
|
||||
PyException_SetTraceback(value, trace);
|
||||
#endif
|
||||
if (value)
|
||||
result += str(value).cast<std::string>();
|
||||
|
||||
#if !defined(PYPY_VERSION)
|
||||
if (trace) {
|
||||
PyTracebackObject *tb = (PyTracebackObject *) trace;
|
||||
|
||||
/* Get the deepest trace possible */
|
||||
// Get the deepest trace possible.
|
||||
while (tb->tb_next)
|
||||
tb = tb->tb_next;
|
||||
|
||||
PyFrameObject *frame = tb->tb_frame;
|
||||
errorString += "\n\nAt:\n";
|
||||
result += "\n\nAt:\n";
|
||||
while (frame) {
|
||||
int lineno = PyFrame_GetLineNumber(frame);
|
||||
errorString +=
|
||||
result +=
|
||||
" " + handle(frame->f_code->co_filename).cast<std::string>() +
|
||||
"(" + std::to_string(lineno) + "): " +
|
||||
handle(frame->f_code->co_name).cast<std::string>() + "\n";
|
||||
@ -445,12 +436,13 @@ PYBIND11_NOINLINE inline std::string error_string(PyObject* type, PyObject* valu
|
||||
}
|
||||
#endif
|
||||
|
||||
return errorString;
|
||||
return result;
|
||||
}
|
||||
|
||||
PYBIND11_NOINLINE inline std::string error_string() {
|
||||
error_scope scope; // Preserve error state
|
||||
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
|
||||
error_scope scope; // Preserve error state.
|
||||
if (scope.type)
|
||||
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
|
||||
return error_string(scope.type, scope.value, scope.trace);
|
||||
}
|
||||
|
||||
|
@ -333,17 +333,16 @@ public:
|
||||
|
||||
inline ~error_already_set();
|
||||
|
||||
virtual const char* what() const noexcept {
|
||||
try {
|
||||
if (m_lazy_what.empty()) {
|
||||
if (m_type || m_value || m_trace)
|
||||
virtual const char* what() const noexcept override {
|
||||
if (m_lazy_what.empty()) {
|
||||
try {
|
||||
PyErr_NormalizeException(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());
|
||||
m_lazy_what = detail::error_string(m_type.ptr(), m_value.ptr(), m_trace.ptr());
|
||||
} catch (...) {
|
||||
return "Unknown internal error occurred";
|
||||
}
|
||||
return m_lazy_what.c_str();
|
||||
} catch (...) {
|
||||
return "Unknown internal error occurred";
|
||||
}
|
||||
return m_lazy_what.c_str();
|
||||
}
|
||||
|
||||
/// Give the currently-held error back to Python, if any. If there is currently a Python error
|
||||
@ -351,7 +350,7 @@ public:
|
||||
/// error variables (but the `.what()` string is still available).
|
||||
void restore() {
|
||||
what(); // Force-build `.what()`.
|
||||
if (m_type || m_value || m_trace)
|
||||
if (m_type)
|
||||
PyErr_Restore(m_type.release().ptr(), m_value.release().ptr(), m_trace.release().ptr());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user