static void print_exception(PyObject *f, PyObject *value) { int err = 0; PyObject *type, *tb; _Py_IDENTIFIER(print_file_and_line); if (!PyExceptionInstance_Check(value)) { err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); err += PyFile_WriteString(Py_TYPE(value)->tp_name, f); err += PyFile_WriteString(" found\n", f); if (err) PyErr_Clear(); return; } Py_INCREF(value); fflush(stdout); type = (PyObject *) Py_TYPE(value); tb = PyException_GetTraceback(value); if (tb && tb != Py_None) err = PyTraceBack_Print(tb, f); if (err == 0 && _PyObject_HasAttrId(value, &PyId_print_file_and_line)) { PyObject *message, *filename, *text; int lineno, offset; if (!parse_syntax_error(value, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); else { PyObject *line; Py_DECREF(value); value = message; line = PyUnicode_FromFormat(" File \"%U\", line %d\n", filename, lineno); Py_DECREF(filename); if (line != NULL) { PyFile_WriteObject(line, f, Py_PRINT_RAW); Py_DECREF(line); } if (text != NULL) { print_error_text(f, offset, text); Py_DECREF(text); } /* Can't be bothered to check all those PyFile_WriteString() calls */ if (PyErr_Occurred()) err = -1; } } if (err) { /* Don't do anything else */ } else { PyObject* moduleName; char* className; _Py_IDENTIFIER(__module__); assert(PyExceptionClass_Check(type)); className = PyExceptionClass_Name(type); if (className != NULL) { char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = _PyObject_GetAttrId(type, &PyId___module__); if (moduleName == NULL || !PyUnicode_Check(moduleName)) { Py_XDECREF(moduleName); err = PyFile_WriteString("<unknown>", f); } else { if (_PyUnicode_CompareWithId(moduleName, &PyId_builtins) != 0) { err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW); err += PyFile_WriteString(".", f); } Py_DECREF(moduleName); } if (err == 0) { if (className == NULL) err = PyFile_WriteString("<unknown>", f); else err = PyFile_WriteString(className, f); } } if (err == 0 && (value != Py_None)) { PyObject *s = PyObject_Str(value); /* only print colon if the str() of the object is not the empty string */ if (s == NULL) err = -1; else if (!PyUnicode_Check(s) || PyUnicode_GetLength(s) != 0) err = PyFile_WriteString(": ", f); if (err == 0) err = PyFile_WriteObject(s, f, Py_PRINT_RAW); Py_XDECREF(s); } /* try to write a newline in any case */ err += PyFile_WriteString("\n", f); Py_XDECREF(tb); Py_DECREF(value); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ if (err != 0) PyErr_Clear(); }
/* Call when an exception has occurred but there is no way for Python to handle it. Examples: exception in __del__ or during GC. */ void PyErr_WriteUnraisable(PyObject *obj) { _Py_IDENTIFIER(__module__); PyObject *f, *t, *v, *tb; PyObject *moduleName = NULL; char* className; PyErr_Fetch(&t, &v, &tb); f = _PySys_GetObjectId(&PyId_stderr); if (f == NULL || f == Py_None) goto done; if (obj) { if (PyFile_WriteString("Exception ignored in: ", f) < 0) goto done; if (PyFile_WriteObject(obj, f, 0) < 0) { PyErr_Clear(); if (PyFile_WriteString("<object repr() failed>", f) < 0) { goto done; } } if (PyFile_WriteString("\n", f) < 0) goto done; } if (PyTraceBack_Print(tb, f) < 0) goto done; if (!t) goto done; assert(PyExceptionClass_Check(t)); className = PyExceptionClass_Name(t); if (className != NULL) { char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = _PyObject_GetAttrId(t, &PyId___module__); if (moduleName == NULL) { PyErr_Clear(); if (PyFile_WriteString("<unknown>", f) < 0) goto done; } else { if (_PyUnicode_CompareWithId(moduleName, &PyId_builtins) != 0) { if (PyFile_WriteObject(moduleName, f, Py_PRINT_RAW) < 0) goto done; if (PyFile_WriteString(".", f) < 0) goto done; } } if (className == NULL) { if (PyFile_WriteString("<unknown>", f) < 0) goto done; } else { if (PyFile_WriteString(className, f) < 0) goto done; } if (v && v != Py_None) { if (PyFile_WriteString(": ", f) < 0) goto done; if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) { PyErr_Clear(); if (PyFile_WriteString("<exception str() failed>", f) < 0) { goto done; } } } if (PyFile_WriteString("\n", f) < 0) goto done; done: Py_XDECREF(moduleName); Py_XDECREF(t); Py_XDECREF(v); Py_XDECREF(tb); PyErr_Clear(); /* Just in case */ }