mirror of
https://github.com/python/cpython
synced 2024-10-14 11:18:47 +00:00
bpo-45635: refactor print_exception() into smaller functions (GH-29981)
Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
This commit is contained in:
parent
d4363d2140
commit
f893bb2e01
|
@ -908,38 +908,35 @@ write_indented_margin(struct exception_print_context *ctx, PyObject *f)
|
|||
return _Py_WriteIndentedMargin(EXC_INDENT(ctx), EXC_MARGIN(ctx), f);
|
||||
}
|
||||
|
||||
static void
|
||||
print_exception(struct exception_print_context *ctx, PyObject *value)
|
||||
static int
|
||||
print_exception_invalid_type(struct exception_print_context *ctx,
|
||||
PyObject *value)
|
||||
{
|
||||
int err = 0;
|
||||
PyObject *type, *tb, *tmp;
|
||||
PyObject *f = ctx->file;
|
||||
|
||||
_Py_IDENTIFIER(print_file_and_line);
|
||||
|
||||
if (!PyExceptionInstance_Check(value)) {
|
||||
if (err == 0) {
|
||||
err = _Py_WriteIndent(EXC_INDENT(ctx), f);
|
||||
}
|
||||
if (err == 0) {
|
||||
err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f);
|
||||
}
|
||||
if (err == 0) {
|
||||
err = PyFile_WriteString(Py_TYPE(value)->tp_name, f);
|
||||
}
|
||||
if (err == 0) {
|
||||
err = PyFile_WriteString(" found\n", f);
|
||||
}
|
||||
if (err != 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
return;
|
||||
if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
const char *const msg = "TypeError: print_exception(): Exception expected "
|
||||
"for value, ";
|
||||
if (PyFile_WriteString(msg, f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (PyFile_WriteString(Py_TYPE(value)->tp_name, f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (PyFile_WriteString(" found\n", f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_INCREF(value);
|
||||
fflush(stdout);
|
||||
type = (PyObject *) Py_TYPE(value);
|
||||
tb = PyException_GetTraceback(value);
|
||||
static int
|
||||
print_exception_traceback(struct exception_print_context *ctx, PyObject *value)
|
||||
{
|
||||
PyObject *f = ctx->file;
|
||||
int err = 0;
|
||||
|
||||
PyObject *tb = PyException_GetTraceback(value);
|
||||
if (tb && tb != Py_None) {
|
||||
const char *header = EXCEPTION_TB_HEADER;
|
||||
const char *header_margin = EXC_MARGIN(ctx);
|
||||
|
@ -952,6 +949,117 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
|
|||
err = _PyTraceBack_Print_Indented(
|
||||
tb, EXC_INDENT(ctx), EXC_MARGIN(ctx), header_margin, header, f);
|
||||
}
|
||||
Py_XDECREF(tb);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Prints the message line: module.qualname[: str(exc)] */
|
||||
static int
|
||||
print_exception_message(struct exception_print_context *ctx, PyObject *type,
|
||||
PyObject *value)
|
||||
{
|
||||
PyObject *f = ctx->file;
|
||||
|
||||
_Py_IDENTIFIER(__module__);
|
||||
|
||||
assert(PyExceptionClass_Check(type));
|
||||
|
||||
if (write_indented_margin(ctx, f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyObject *modulename = _PyObject_GetAttrId(type, &PyId___module__);
|
||||
if (modulename == NULL || !PyUnicode_Check(modulename)) {
|
||||
Py_XDECREF(modulename);
|
||||
PyErr_Clear();
|
||||
if (PyFile_WriteString("<unknown>.", f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins) &&
|
||||
!_PyUnicode_EqualToASCIIId(modulename, &PyId___main__))
|
||||
{
|
||||
int res = PyFile_WriteObject(modulename, f, Py_PRINT_RAW);
|
||||
Py_DECREF(modulename);
|
||||
if (res < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (PyFile_WriteString(".", f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Py_DECREF(modulename);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *qualname = PyType_GetQualName((PyTypeObject *)type);
|
||||
if (qualname == NULL || !PyUnicode_Check(qualname)) {
|
||||
Py_XDECREF(qualname);
|
||||
PyErr_Clear();
|
||||
if (PyFile_WriteString("<unknown>", f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int res = PyFile_WriteObject(qualname, f, Py_PRINT_RAW);
|
||||
Py_DECREF(qualname);
|
||||
if (res < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Py_IsNone(value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject *s = PyObject_Str(value);
|
||||
if (s == NULL) {
|
||||
PyErr_Clear();
|
||||
if (PyFile_WriteString(": <exception str() failed>", f) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* only print colon if the str() of the
|
||||
object is not the empty string
|
||||
*/
|
||||
if (!PyUnicode_Check(s) || PyUnicode_GetLength(s) != 0) {
|
||||
if (PyFile_WriteString(": ", f) < 0) {
|
||||
Py_DECREF(s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
int res = PyFile_WriteObject(s, f, Py_PRINT_RAW);
|
||||
Py_DECREF(s);
|
||||
if (res < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
print_exception(struct exception_print_context *ctx, PyObject *value)
|
||||
{
|
||||
int err = 0;
|
||||
PyObject *tmp;
|
||||
PyObject *f = ctx->file;
|
||||
|
||||
_Py_IDENTIFIER(print_file_and_line);
|
||||
|
||||
if (!PyExceptionInstance_Check(value)) {
|
||||
if (print_exception_invalid_type(ctx, value) < 0) {
|
||||
PyErr_Clear(); /* TODO: change to return -1 */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Py_INCREF(value);
|
||||
fflush(stdout);
|
||||
PyObject *type = (PyObject *) Py_TYPE(value);
|
||||
err = print_exception_traceback(ctx, value);
|
||||
if (err == 0 &&
|
||||
(err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0)
|
||||
{
|
||||
|
@ -1006,66 +1114,11 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
|
|||
err = -1;
|
||||
}
|
||||
}
|
||||
if (err != 0) {
|
||||
/* Don't do anything else */
|
||||
}
|
||||
else {
|
||||
PyObject* modulename;
|
||||
|
||||
_Py_IDENTIFIER(__module__);
|
||||
assert(PyExceptionClass_Check(type));
|
||||
if (err == 0) {
|
||||
err = print_exception_message(ctx, type, value);
|
||||
}
|
||||
|
||||
err = write_indented_margin(ctx, f);
|
||||
if (err == 0) {
|
||||
modulename = _PyObject_GetAttrId(type, &PyId___module__);
|
||||
if (modulename == NULL || !PyUnicode_Check(modulename))
|
||||
{
|
||||
Py_XDECREF(modulename);
|
||||
PyErr_Clear();
|
||||
err = PyFile_WriteString("<unknown>.", f);
|
||||
}
|
||||
else {
|
||||
if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins) &&
|
||||
!_PyUnicode_EqualToASCIIId(modulename, &PyId___main__))
|
||||
{
|
||||
err = PyFile_WriteObject(modulename, f, Py_PRINT_RAW);
|
||||
if (err == 0) {
|
||||
err = PyFile_WriteString(".", f);
|
||||
}
|
||||
}
|
||||
Py_DECREF(modulename);
|
||||
}
|
||||
}
|
||||
if (err == 0) {
|
||||
PyObject* qualname = PyType_GetQualName((PyTypeObject *)type);
|
||||
if (qualname == NULL || !PyUnicode_Check(qualname)) {
|
||||
Py_XDECREF(qualname);
|
||||
PyErr_Clear();
|
||||
err = PyFile_WriteString("<unknown>", f);
|
||||
}
|
||||
else {
|
||||
err = PyFile_WriteObject(qualname, f, Py_PRINT_RAW);
|
||||
Py_DECREF(qualname);
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
PyErr_Clear();
|
||||
err = -1;
|
||||
PyFile_WriteString(": <exception str() failed>", f);
|
||||
}
|
||||
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 */
|
||||
if (err < 0) {
|
||||
PyErr_Clear();
|
||||
|
@ -1118,7 +1171,6 @@ print_exception(struct exception_print_context *ctx, PyObject *value)
|
|||
}
|
||||
Py_XDECREF(note);
|
||||
}
|
||||
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. */
|
||||
|
|
Loading…
Reference in a new issue