diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2023-03-16 10:16:01 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-16 10:16:01 (GMT) |
commit | 51d693c58454a2c525094a7c74ebac86859353fd (patch) | |
tree | 9c5bd67c259638864cc3e57031ead3707355ba8d /Python/errors.c | |
parent | 2dc94634b50f0e5e207787e5ac1d56c68b22c3ae (diff) | |
download | cpython-51d693c58454a2c525094a7c74ebac86859353fd.zip cpython-51d693c58454a2c525094a7c74ebac86859353fd.tar.gz cpython-51d693c58454a2c525094a7c74ebac86859353fd.tar.bz2 |
gh-102594: PyErr_SetObject adds note to exception raised on normalization error (#102675)
Diffstat (limited to 'Python/errors.c')
-rw-r--r-- | Python/errors.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/Python/errors.c b/Python/errors.c index bbf6d39..bdcbac3 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -135,6 +135,28 @@ _PyErr_GetTopmostException(PyThreadState *tstate) return exc_info; } +static PyObject * +get_normalization_failure_note(PyThreadState *tstate, PyObject *exception, PyObject *value) +{ + PyObject *args = PyObject_Repr(value); + if (args == NULL) { + _PyErr_Clear(tstate); + args = PyUnicode_FromFormat("<unknown>"); + } + PyObject *note; + const char *tpname = ((PyTypeObject*)exception)->tp_name; + if (args == NULL) { + _PyErr_Clear(tstate); + note = PyUnicode_FromFormat("Normalization failed: type=%s", tpname); + } + else { + note = PyUnicode_FromFormat("Normalization failed: type=%s args=%S", + tpname, args); + Py_DECREF(args); + } + return note; +} + void _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) { @@ -160,19 +182,27 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) Py_XINCREF(value); if (!is_subclass) { /* We must normalize the value right now */ - PyObject *fixed_value; /* Issue #23571: functions must not be called with an exception set */ _PyErr_Clear(tstate); - fixed_value = _PyErr_CreateException(exception, value); - Py_XDECREF(value); + PyObject *fixed_value = _PyErr_CreateException(exception, value); if (fixed_value == NULL) { + PyObject *exc = _PyErr_GetRaisedException(tstate); + assert(PyExceptionInstance_Check(exc)); + + PyObject *note = get_normalization_failure_note(tstate, exception, value); + Py_XDECREF(value); + if (note != NULL) { + /* ignore errors in _PyException_AddNote - they will be overwritten below */ + _PyException_AddNote(exc, note); + Py_DECREF(note); + } + _PyErr_SetRaisedException(tstate, exc); return; } - - value = fixed_value; + Py_XSETREF(value, fixed_value); } exc_value = _PyErr_GetTopmostException(tstate)->exc_value; |