diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2022-01-02 23:22:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-02 23:22:42 (GMT) |
commit | 65e7c1f90e9136fc61f4af029b065d9f6c5664c3 (patch) | |
tree | bf322965684bd0eeef7c220c5d1cb8307933cbb7 /Python/ceval.c | |
parent | 8e75c6b49b7cb8515b917f01b32ece8c8ea2c0a0 (diff) | |
download | cpython-65e7c1f90e9136fc61f4af029b065d9f6c5664c3.zip cpython-65e7c1f90e9136fc61f4af029b065d9f6c5664c3.tar.gz cpython-65e7c1f90e9136fc61f4af029b065d9f6c5664c3.tar.bz2 |
bpo-46219, 46221: simplify except* implementation following exc_info changes. Move helpers to exceptions.c. Do not assume that exception groups are truthy. (GH-30289)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 133 |
1 files changed, 1 insertions, 132 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 9976bde..43925e6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1092,7 +1092,6 @@ fail: static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); -static PyObject *do_reraise_star(PyObject *excs, PyObject *orig); static int exception_group_match( PyObject* exc_value, PyObject *match_type, PyObject **match, PyObject **rest); @@ -2777,7 +2776,7 @@ check_eval_breaker: assert(PyList_Check(excs)); PyObject *orig = POP(); - PyObject *val = do_reraise_star(excs, orig); + PyObject *val = _PyExc_PrepReraiseStar(orig, excs); Py_DECREF(excs); Py_DECREF(orig); @@ -2785,8 +2784,6 @@ check_eval_breaker: goto error; } - PyObject *lasti_unused = Py_NewRef(_PyLong_GetZero()); - PUSH(lasti_unused); PUSH(val); DISPATCH(); } @@ -6313,134 +6310,6 @@ exception_group_match(PyObject* exc_value, PyObject *match_type, return 0; } -/* Logic for the final raise/reraise of a try-except* contruct - (too complicated for inlining). -*/ - -static bool -is_same_exception_metadata(PyObject *exc1, PyObject *exc2) -{ - assert(PyExceptionInstance_Check(exc1)); - assert(PyExceptionInstance_Check(exc2)); - - PyObject *tb1 = PyException_GetTraceback(exc1); - PyObject *ctx1 = PyException_GetContext(exc1); - PyObject *cause1 = PyException_GetCause(exc1); - PyObject *tb2 = PyException_GetTraceback(exc2); - PyObject *ctx2 = PyException_GetContext(exc2); - PyObject *cause2 = PyException_GetCause(exc2); - - bool result = (Py_Is(tb1, tb2) && - Py_Is(ctx1, ctx2) && - Py_Is(cause1, cause2)); - - Py_XDECREF(tb1); - Py_XDECREF(ctx1); - Py_XDECREF(cause1); - Py_XDECREF(tb2); - Py_XDECREF(ctx2); - Py_XDECREF(cause2); - return result; -} - -/* - excs: a list of exceptions to raise/reraise - orig: the original except that was caught - - Calculates an exception group to raise. It contains - all exceptions in excs, where those that were reraised - have same nesting structure as in orig, and those that - were raised (if any) are added as siblings in a new EG. - - Returns NULL and sets an exception on failure. -*/ -static PyObject * -do_reraise_star(PyObject *excs, PyObject *orig) -{ - assert(PyList_Check(excs)); - assert(PyExceptionInstance_Check(orig)); - - Py_ssize_t numexcs = PyList_GET_SIZE(excs); - - if (numexcs == 0) { - return Py_NewRef(Py_None); - } - - if (!_PyBaseExceptionGroup_Check(orig)) { - /* a naked exception was caught and wrapped. Only one except* clause - * could have executed,so there is at most one exception to raise. - */ - - assert(numexcs == 1 || (numexcs == 2 && PyList_GET_ITEM(excs, 1) == Py_None)); - - PyObject *e = PyList_GET_ITEM(excs, 0); - assert(e != NULL); - return Py_NewRef(e); - } - - - PyObject *raised_list = PyList_New(0); - if (raised_list == NULL) { - return NULL; - } - PyObject* reraised_list = PyList_New(0); - if (reraised_list == NULL) { - Py_DECREF(raised_list); - return NULL; - } - - /* Now we are holding refs to raised_list and reraised_list */ - - PyObject *result = NULL; - - /* Split excs into raised and reraised by comparing metadata with orig */ - for (Py_ssize_t i = 0; i < numexcs; i++) { - PyObject *e = PyList_GET_ITEM(excs, i); - assert(e != NULL); - if (Py_IsNone(e)) { - continue; - } - bool is_reraise = is_same_exception_metadata(e, orig); - PyObject *append_list = is_reraise ? reraised_list : raised_list; - if (PyList_Append(append_list, e) < 0) { - goto done; - } - } - - PyObject *reraised_eg = _PyExc_ExceptionGroupProjection(orig, reraised_list); - if (reraised_eg == NULL) { - goto done; - } - - if (!Py_IsNone(reraised_eg)) { - assert(is_same_exception_metadata(reraised_eg, orig)); - } - - Py_ssize_t num_raised = PyList_GET_SIZE(raised_list); - if (num_raised == 0) { - result = reraised_eg; - } - else if (num_raised > 0) { - int res = 0; - if (!Py_IsNone(reraised_eg)) { - res = PyList_Append(raised_list, reraised_eg); - } - Py_DECREF(reraised_eg); - if (res < 0) { - goto done; - } - result = _PyExc_CreateExceptionGroup("", raised_list); - if (result == NULL) { - goto done; - } - } - -done: - Py_XDECREF(raised_list); - Py_XDECREF(reraised_list); - return result; -} - /* Iterate v argcnt times and store the results on the stack (via decreasing sp). Return 1 for success, 0 if error. |