[Python-checkins] bpo-45635: refactor print_exception() into smaller functions (GH-29981)

iritkatriel webhook-mailer at python.org
Wed Dec 8 13:47:36 EST 2021


https://github.com/python/cpython/commit/f893bb2e01307c92ca19597f44874ecaffe7f06f
commit: f893bb2e01307c92ca19597f44874ecaffe7f06f
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2021-12-08T18:47:27Z
summary:

bpo-45635: refactor print_exception() into smaller functions (GH-29981)

Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at innova.no>

files:
M Python/pythonrun.c

diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 5a118b4821ec0..cfc39361d5fcb 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. */



More information about the Python-checkins mailing list