summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2022-04-16 18:59:52 (GMT)
committerGitHub <noreply@github.com>2022-04-16 18:59:52 (GMT)
commitd4c4a76ed1427c947fcbbe692625b3f644cf3aaf (patch)
tree2e503da40ff6459711ff5730b22e89962b175252 /Python
parent7fa3a5a2197896066e3fe53ee325ac6ab54c3414 (diff)
downloadcpython-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.c81
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;
}