diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2021-12-08 18:47:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-08 18:47:27 (GMT) |
commit | f893bb2e01307c92ca19597f44874ecaffe7f06f (patch) | |
tree | 6358e1fc8d3b6421a18f02147244d56673307f94 /Python/pythonrun.c | |
parent | d4363d214097b3fca8b7910c2e0e91c8b0873fb2 (diff) | |
download | cpython-f893bb2e01307c92ca19597f44874ecaffe7f06f.zip cpython-f893bb2e01307c92ca19597f44874ecaffe7f06f.tar.gz cpython-f893bb2e01307c92ca19597f44874ecaffe7f06f.tar.bz2 |
bpo-45635: refactor print_exception() into smaller functions (GH-29981)
Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
Diffstat (limited to 'Python/pythonrun.c')
-rw-r--r-- | Python/pythonrun.c | 226 |
1 files changed, 139 insertions, 87 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 5a118b4..cfc3936 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -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)); - - 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); + if (err == 0) { + err = print_exception_message(ctx, type, value); } + /* 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. */ |