diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2022-04-16 18:59:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-16 18:59:52 (GMT) |
commit | d4c4a76ed1427c947fcbbe692625b3f644cf3aaf (patch) | |
tree | 2e503da40ff6459711ff5730b22e89962b175252 /Python | |
parent | 7fa3a5a2197896066e3fe53ee325ac6ab54c3414 (diff) | |
download | cpython-d4c4a76ed1427c947fcbbe692625b3f644cf3aaf.zip cpython-d4c4a76ed1427c947fcbbe692625b3f644cf3aaf.tar.gz cpython-d4c4a76ed1427c947fcbbe692625b3f644cf3aaf.tar.bz2 |
gh-89770: Implement PEP-678 - Exception notes (GH-31317)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pythonrun.c | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index e086f0f..769c34e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1129,7 +1129,7 @@ error: } static int -print_exception_note(struct exception_print_context *ctx, PyObject *value) +print_exception_notes(struct exception_print_context *ctx, PyObject *value) { PyObject *f = ctx->file; @@ -1137,41 +1137,74 @@ print_exception_note(struct exception_print_context *ctx, PyObject *value) return 0; } - PyObject *note = PyObject_GetAttr(value, &_Py_ID(__note__)); - if (note == NULL) { + if (!PyObject_HasAttr(value, &_Py_ID(__notes__))) { + return 0; + } + PyObject *notes = PyObject_GetAttr(value, &_Py_ID(__notes__)); + if (notes == NULL) { return -1; } - if (!PyUnicode_Check(note)) { - Py_DECREF(note); - return 0; + if (!PySequence_Check(notes)) { + int res = 0; + if (write_indented_margin(ctx, f) < 0) { + res = -1; + } + PyObject *s = PyObject_Repr(notes); + if (s == NULL) { + PyErr_Clear(); + res = PyFile_WriteString("<__notes__ repr() failed>", f); + } + else { + res = PyFile_WriteObject(s, f, Py_PRINT_RAW); + Py_DECREF(s); + } + Py_DECREF(notes); + return res; } + Py_ssize_t num_notes = PySequence_Length(notes); + PyObject *lines = NULL; + for (Py_ssize_t ni = 0; ni < num_notes; ni++) { + PyObject *note = PySequence_GetItem(notes, ni); + PyObject *note_str = PyObject_Str(note); + Py_DECREF(note); - PyObject *lines = PyUnicode_Splitlines(note, 1); - Py_DECREF(note); + if (note_str == NULL) { + PyErr_Clear(); + if (PyFile_WriteString("<note str() failed>", f) < 0) { + goto error; + } + } + else { + lines = PyUnicode_Splitlines(note_str, 1); + Py_DECREF(note_str); - if (lines == NULL) { - return -1; - } + if (lines == NULL) { + goto error; + } - 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; + 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; + } + } + Py_CLEAR(lines); } - if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) { + if (PyFile_WriteString("\n", f) < 0) { goto error; } } - if (PyFile_WriteString("\n", f) < 0) { - goto error; - } - Py_DECREF(lines); + Py_DECREF(notes); return 0; error: - Py_DECREF(lines); + Py_XDECREF(lines); + Py_DECREF(notes); return -1; } @@ -1206,7 +1239,7 @@ print_exception(struct exception_print_context *ctx, PyObject *value) if (PyFile_WriteString("\n", f) < 0) { goto error; } - if (print_exception_note(ctx, value) < 0) { + if (print_exception_notes(ctx, value) < 0) { goto error; } |