summaryrefslogtreecommitdiffstats
path: root/Python/pythonrun.c
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2021-12-08 18:47:27 (GMT)
committerGitHub <noreply@github.com>2021-12-08 18:47:27 (GMT)
commitf893bb2e01307c92ca19597f44874ecaffe7f06f (patch)
tree6358e1fc8d3b6421a18f02147244d56673307f94 /Python/pythonrun.c
parentd4363d214097b3fca8b7910c2e0e91c8b0873fb2 (diff)
downloadcpython-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.c226
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. */