detail::error_string: handle call stacks that switch between C++ and Python multiple times

This commit is contained in:
Wenzel Jakob 2016-11-24 12:31:06 +01:00
parent fbec17ce90
commit e72d958a5d

View File

@ -136,9 +136,19 @@ PYBIND11_NOINLINE inline std::string error_string() {
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace); PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
#if PY_MAJOR_VERSION >= 3
if (scope.trace != nullptr)
PyException_SetTraceback(scope.value, scope.trace);
#endif
if (scope.trace) { if (scope.trace) {
PyFrameObject *frame = ((PyTracebackObject *) scope.trace)->tb_frame; PyTracebackObject *trace = (PyTracebackObject *) scope.trace;
if (frame) {
/* Get the deepest trace possible */
while (trace->tb_next)
trace = trace->tb_next;
PyFrameObject *frame = trace->tb_frame;
errorString += "\n\nAt:\n"; errorString += "\n\nAt:\n";
while (frame) { while (frame) {
int lineno = PyFrame_GetLineNumber(frame); int lineno = PyFrame_GetLineNumber(frame);
@ -148,7 +158,7 @@ PYBIND11_NOINLINE inline std::string error_string() {
handle(frame->f_code->co_name).cast<std::string>() + "\n"; handle(frame->f_code->co_name).cast<std::string>() + "\n";
frame = frame->f_back; frame = frame->f_back;
} }
} trace = trace->tb_next;
} }
return errorString; return errorString;