diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2021-12-09 14:38:00 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-09 14:38:00 (GMT) |
commit | dc4a212bd305831cb4b187a2e0cc82666fcb15ca (patch) | |
tree | 2485dae34cf246399ae939350935b87b5aca3be9 | |
parent | b123ad8030a4ad15c8dbb7cb3638caf625943878 (diff) | |
download | cpython-dc4a212bd305831cb4b187a2e0cc82666fcb15ca.zip cpython-dc4a212bd305831cb4b187a2e0cc82666fcb15ca.tar.gz cpython-dc4a212bd305831cb4b187a2e0cc82666fcb15ca.tar.bz2 |
bpo-45635: continue refactor of print_exception() to standardize error handling (GH-29996)
Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
-rw-r--r-- | Python/pythonrun.c | 183 |
1 files changed, 105 insertions, 78 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index cfc3936..74b497c 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1040,6 +1040,78 @@ print_exception_message(struct exception_print_context *ctx, PyObject *type, return 0; } +static int +print_exception_suggestions(struct exception_print_context *ctx, + PyObject *value) +{ + PyObject *f = ctx->file; + PyObject *suggestions = _Py_Offer_Suggestions(value); + if (suggestions) { + // Add a trailer ". Did you mean: (...)?" + if (PyFile_WriteString(". Did you mean: '", f) < 0) { + goto error; + } + if (PyFile_WriteObject(suggestions, f, Py_PRINT_RAW) < 0) { + goto error; + } + if (PyFile_WriteString("'?", f) < 0) { + goto error; + } + Py_DECREF(suggestions); + } + else if (PyErr_Occurred()) { + PyErr_Clear(); + } + return 0; +error: + Py_XDECREF(suggestions); + return -1; +} + +static int +print_exception_note(struct exception_print_context *ctx, PyObject *value) +{ + PyObject *f = ctx->file; + _Py_IDENTIFIER(__note__); + + PyObject *note = _PyObject_GetAttrId(value, &PyId___note__); + if (note == NULL) { + return -1; + } + if (!PyUnicode_Check(note)) { + Py_DECREF(note); + return 0; + } + + PyObject *lines = PyUnicode_Splitlines(note, 1); + Py_DECREF(note); + + if (lines == NULL) { + return -1; + } + + Py_ssize_t n = PyList_GET_SIZE(lines); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *line = PyList_GET_ITEM(lines, i); + assert(PyUnicode_Check(line)); + if (write_indented_margin(ctx, f) < 0) { + goto error; + } + if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) { + goto error; + } + } + if (PyFile_WriteString("\n", f) < 0) { + goto error; + } + + Py_DECREF(lines); + return 0; +error: + Py_DECREF(lines); + return -1; +} + static void print_exception(struct exception_print_context *ctx, PyObject *value) { @@ -1073,13 +1145,12 @@ print_exception(struct exception_print_context *ctx, PyObject *value) PyErr_Clear(); } else { - PyObject *line; Py_DECREF(value); value = message; - line = PyUnicode_FromFormat(" File \"%S\", line %zd\n", - filename, lineno); + PyObject *line = PyUnicode_FromFormat(" File \"%S\", line %zd\n", + filename, lineno); Py_DECREF(filename); if (line != NULL) { err = write_indented_margin(ctx, f); @@ -1118,59 +1189,16 @@ print_exception(struct exception_print_context *ctx, PyObject *value) if (err == 0) { err = print_exception_message(ctx, type, value); } - - /* try to write a newline in any case */ - if (err < 0) { - PyErr_Clear(); + if (err == 0) { + err = print_exception_suggestions(ctx, value); } - PyObject* suggestions = _Py_Offer_Suggestions(value); - if (suggestions) { - // Add a trailer ". Did you mean: (...)?" - err = PyFile_WriteString(". Did you mean: '", f); - if (err == 0) { - err = PyFile_WriteObject(suggestions, f, Py_PRINT_RAW); - err += PyFile_WriteString("'?", f); - } - Py_DECREF(suggestions); - } else if (PyErr_Occurred()) { - PyErr_Clear(); + if (err == 0) { + err = PyFile_WriteString("\n", f); } - err += PyFile_WriteString("\n", f); - if (err == 0 && PyExceptionInstance_Check(value)) { - _Py_IDENTIFIER(__note__); - - PyObject *note = _PyObject_GetAttrId(value, &PyId___note__); - if (note == NULL) { - err = -1; - } - if (err == 0 && PyUnicode_Check(note)) { - _Py_static_string(PyId_newline, "\n"); - PyObject *lines = PyUnicode_Split( - note, _PyUnicode_FromId(&PyId_newline), -1); - if (lines == NULL) { - err = -1; - } - else { - Py_ssize_t n = PyList_GET_SIZE(lines); - for (Py_ssize_t i = 0; i < n; i++) { - if (err == 0) { - PyObject *line = PyList_GET_ITEM(lines, i); - assert(PyUnicode_Check(line)); - err = write_indented_margin(ctx, f); - if (err == 0) { - err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - } - if (err == 0) { - err = PyFile_WriteString("\n", f); - } - } - } - } - Py_DECREF(lines); - } - Py_XDECREF(note); + err = print_exception_note(ctx, value); } + Py_DECREF(value); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ @@ -1194,36 +1222,35 @@ print_chained(struct exception_print_context* ctx, PyObject *value, const char * message, const char *tag) { PyObject *f = ctx->file; - bool need_close = ctx->need_close; - - int err = Py_EnterRecursiveCall(" in print_chained"); - if (err == 0) { - print_exception_recursive(ctx, value); - Py_LeaveRecursiveCall(); - if (err == 0) { - err = write_indented_margin(ctx, f); - } - if (err == 0) { - err = PyFile_WriteString("\n", f); - } - if (err == 0) { - err = write_indented_margin(ctx, f); - } - if (err == 0) { - err = PyFile_WriteString(message, f); - } - if (err == 0) { - err = write_indented_margin(ctx, f); - } - if (err == 0) { - err = PyFile_WriteString("\n", f); - } + if (Py_EnterRecursiveCall(" in print_chained") < 0) { + return -1; } - + bool need_close = ctx->need_close; + print_exception_recursive(ctx, value); ctx->need_close = need_close; - return err; + Py_LeaveRecursiveCall(); + + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + if (PyFile_WriteString("\n", f) < 0) { + return -1; + } + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + if (PyFile_WriteString(message, f) < 0) { + return -1; + } + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + if (PyFile_WriteString("\n", f) < 0) { + return -1; + } + return 0; } static void |