mirror of
https://github.com/pybind/pybind11.git
synced 2024-12-03 18:37: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);
|
return isinstance(obj, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_NOINLINE inline std::string error_string(PyObject* type, PyObject* value, PyObject *trace) {
|
PYBIND11_NOINLINE inline std::string error_string(PyObject *type, PyObject *value, PyObject *trace) {
|
||||||
if (!type && !value && !trace) {
|
if (!type) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred");
|
PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred");
|
||||||
return "Unknown internal error occurred";
|
return "Unknown internal error occurred";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(superbobry): is it safe to assume that exception has been
|
std::string result = handle(type).attr("__name__").cast<std::string>();
|
||||||
// normalized by the caller?
|
result += ": ";
|
||||||
std::string errorString;
|
|
||||||
if (type) {
|
|
||||||
errorString += handle(type).attr("__name__").cast<std::string>();
|
|
||||||
errorString += ": ";
|
|
||||||
}
|
|
||||||
if (value)
|
|
||||||
errorString += str(value).cast<std::string>();
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
if (value)
|
||||||
if (trace)
|
result += str(value).cast<std::string>();
|
||||||
PyException_SetTraceback(value, trace);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PYPY_VERSION)
|
#if !defined(PYPY_VERSION)
|
||||||
if (trace) {
|
if (trace) {
|
||||||
PyTracebackObject *tb = (PyTracebackObject *) trace;
|
PyTracebackObject *tb = (PyTracebackObject *) trace;
|
||||||
|
|
||||||
/* Get the deepest trace possible */
|
// Get the deepest trace possible.
|
||||||
while (tb->tb_next)
|
while (tb->tb_next)
|
||||||
tb = tb->tb_next;
|
tb = tb->tb_next;
|
||||||
|
|
||||||
PyFrameObject *frame = tb->tb_frame;
|
PyFrameObject *frame = tb->tb_frame;
|
||||||
errorString += "\n\nAt:\n";
|
result += "\n\nAt:\n";
|
||||||
while (frame) {
|
while (frame) {
|
||||||
int lineno = PyFrame_GetLineNumber(frame);
|
int lineno = PyFrame_GetLineNumber(frame);
|
||||||
errorString +=
|
result +=
|
||||||
" " + handle(frame->f_code->co_filename).cast<std::string>() +
|
" " + handle(frame->f_code->co_filename).cast<std::string>() +
|
||||||
"(" + std::to_string(lineno) + "): " +
|
"(" + std::to_string(lineno) + "): " +
|
||||||
handle(frame->f_code->co_name).cast<std::string>() + "\n";
|
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
|
#endif
|
||||||
|
|
||||||
return errorString;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_NOINLINE inline std::string error_string() {
|
PYBIND11_NOINLINE inline std::string error_string() {
|
||||||
error_scope scope; // Preserve error state
|
error_scope scope; // Preserve error state.
|
||||||
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
|
if (scope.type)
|
||||||
|
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
|
||||||
return error_string(scope.type, scope.value, scope.trace);
|
return error_string(scope.type, scope.value, scope.trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,17 +333,16 @@ public:
|
|||||||
|
|
||||||
inline ~error_already_set();
|
inline ~error_already_set();
|
||||||
|
|
||||||
virtual const char* what() const noexcept {
|
virtual const char* what() const noexcept override {
|
||||||
try {
|
if (m_lazy_what.empty()) {
|
||||||
if (m_lazy_what.empty()) {
|
try {
|
||||||
if (m_type || m_value || m_trace)
|
|
||||||
PyErr_NormalizeException(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());
|
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());
|
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
|
/// 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).
|
/// error variables (but the `.what()` string is still available).
|
||||||
void restore() {
|
void restore() {
|
||||||
what(); // Force-build `.what()`.
|
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());
|
PyErr_Restore(m_type.release().ptr(), m_value.release().ptr(), m_trace.release().ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user