diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2023-05-30 14:03:36 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-30 14:03:36 (GMT) |
commit | b7aadb4583b040ddc8564896b91f4e5e571c82d6 (patch) | |
tree | 665822d1ce0896a4adaa79a7981f6916a6b08d61 /Objects/exceptions.c | |
parent | bd98b65e974b7a1e086a51e7b55131582f7a0491 (diff) | |
download | cpython-b7aadb4583b040ddc8564896b91f4e5e571c82d6.zip cpython-b7aadb4583b040ddc8564896b91f4e5e571c82d6.tar.gz cpython-b7aadb4583b040ddc8564896b91f4e5e571c82d6.tar.bz2 |
gh-105071: add PyUnstable_Exc_PrepReraiseStar to expose except* implementation in the unstable API (#105072)
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r-- | Objects/exceptions.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c index a8d4e3a..7bec739 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1351,7 +1351,10 @@ is_same_exception_metadata(PyObject *exc1, PyObject *exc2) PyObject * _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs) { + /* orig must be a raised & caught exception, so it has a traceback */ assert(PyExceptionInstance_Check(orig)); + assert(_PyBaseExceptionObject_cast(orig)->traceback != NULL); + assert(PyList_Check(excs)); Py_ssize_t numexcs = PyList_GET_SIZE(excs); @@ -1438,6 +1441,42 @@ done: return result; } +PyObject * +PyUnstable_Exc_PrepReraiseStar(PyObject *orig, PyObject *excs) +{ + if (orig == NULL || !PyExceptionInstance_Check(orig)) { + PyErr_SetString(PyExc_TypeError, "orig must be an exception instance"); + return NULL; + } + if (excs == NULL || !PyList_Check(excs)) { + PyErr_SetString(PyExc_TypeError, + "excs must be a list of exception instances"); + return NULL; + } + Py_ssize_t numexcs = PyList_GET_SIZE(excs); + for (Py_ssize_t i = 0; i < numexcs; i++) { + PyObject *exc = PyList_GET_ITEM(excs, i); + if (exc == NULL || !(PyExceptionInstance_Check(exc) || Py_IsNone(exc))) { + PyErr_Format(PyExc_TypeError, + "item %d of excs is not an exception", i); + return NULL; + } + } + + /* Make sure that orig has something as traceback, in the interpreter + * it always does becuase it's a raised exception. + */ + PyObject *tb = PyException_GetTraceback(orig); + + if (tb == NULL) { + PyErr_Format(PyExc_ValueError, "orig must be a raised exception"); + return NULL; + } + Py_DECREF(tb); + + return _PyExc_PrepReraiseStar(orig, excs); +} + static PyMemberDef BaseExceptionGroup_members[] = { {"message", T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), READONLY, PyDoc_STR("exception message")}, |