gh-89770: Implement PEP-678 - Exception notes (GH-31317)

This commit is contained in:
Irit Katriel 2022-04-16 19:59:52 +01:00 committed by GitHub
parent 7fa3a5a219
commit d4c4a76ed1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 383 additions and 144 deletions

View file

@ -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) {
return -1;
}
if (!PyUnicode_Check(note)) {
Py_DECREF(note);
if (!PyObject_HasAttr(value, &_Py_ID(__notes__))) {
return 0;
}
PyObject *lines = PyUnicode_Splitlines(note, 1);
Py_DECREF(note);
if (lines == NULL) {
PyObject *notes = PyObject_GetAttr(value, &_Py_ID(__notes__));
if (notes == 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 (!PySequence_Check(notes)) {
int res = 0;
if (write_indented_margin(ctx, f) < 0) {
goto error;
res = -1;
}
if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) {
goto error;
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;
}
if (PyFile_WriteString("\n", f) < 0) {
goto error;
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);
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) {
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_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;
}