summaryrefslogtreecommitdiffstats
path: root/Python/errors.c
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2023-03-16 10:16:01 (GMT)
committerGitHub <noreply@github.com>2023-03-16 10:16:01 (GMT)
commit51d693c58454a2c525094a7c74ebac86859353fd (patch)
tree9c5bd67c259638864cc3e57031ead3707355ba8d /Python/errors.c
parent2dc94634b50f0e5e207787e5ac1d56c68b22c3ae (diff)
downloadcpython-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.c40
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;