diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2022-08-19 19:33:44 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-19 19:33:44 (GMT) |
commit | 5bfb3c372bda1113aea1385d4793f073a1d37155 (patch) | |
tree | a6b30a05ec2e5f59eadff759e47529ee76a6c132 /Python/ceval.c | |
parent | 2d9f252c0c08bce0e776b38906c3bbb59a3bd2c5 (diff) | |
download | cpython-5bfb3c372bda1113aea1385d4793f073a1d37155.zip cpython-5bfb3c372bda1113aea1385d4793f073a1d37155.tar.gz cpython-5bfb3c372bda1113aea1385d4793f073a1d37155.tar.bz2 |
GH-90997: Wrap yield from/await in a virtual try/except StopIteration (GH-96010)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 8c17e51..7024add 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2668,6 +2668,9 @@ handle_eval_breaker: } TARGET(YIELD_VALUE) { + // NOTE: It's important that YIELD_VALUE never raises an exception! + // The compiler treats any exception raised here as a failed close() + // or throw() call. assert(oparg == STACK_LEVEL()); assert(frame->is_entry); PyObject *retval = POP(); @@ -2746,6 +2749,26 @@ handle_eval_breaker: } } + TARGET(CLEANUP_THROW) { + assert(throwflag); + PyObject *exc_value = TOP(); + assert(exc_value && PyExceptionInstance_Check(exc_value)); + if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + PyObject *value = ((PyStopIterationObject *)exc_value)->value; + Py_INCREF(value); + Py_DECREF(POP()); // The StopIteration. + Py_DECREF(POP()); // The last sent value. + Py_DECREF(POP()); // The delegated sub-iterator. + PUSH(value); + DISPATCH(); + } + Py_INCREF(exc_value); + PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value)); + PyObject *exc_traceback = PyException_GetTraceback(exc_value); + _PyErr_Restore(tstate, exc_type, exc_value, exc_traceback); + goto exception_unwind; + } + TARGET(LOAD_ASSERTION_ERROR) { PyObject *value = PyExc_AssertionError; Py_INCREF(value); |