diff options
author | Mark Shannon <mark@hotpy.org> | 2022-11-03 11:38:51 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-03 11:38:51 (GMT) |
commit | f4adb975061874566766f7a67206cb7b0439bc11 (patch) | |
tree | 136b2e8b97fd8811cef1d2ff46d31fb61f26183a /Python/bytecodes.c | |
parent | e9ac890c0273aee413aa528cc202c3efa29f1d7a (diff) | |
download | cpython-f4adb975061874566766f7a67206cb7b0439bc11.zip cpython-f4adb975061874566766f7a67206cb7b0439bc11.tar.gz cpython-f4adb975061874566766f7a67206cb7b0439bc11.tar.bz2 |
GH-96793: Implement PEP 479 in bytecode. (GH-99006)
* Handle converting StopIteration to RuntimeError in bytecode.
* Add custom instruction for converting StopIteration into RuntimeError.
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 94a4e76..b0d5627 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1085,6 +1085,49 @@ dummy_func( goto exception_unwind; } + inst(STOPITERATION_ERROR) { + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + PyObject *exc = TOP(); + assert(PyExceptionInstance_Check(exc)); + const char *msg = NULL; + if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) { + msg = "generator raised StopIteration"; + if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) { + msg = "async generator raised StopIteration"; + } + else if (frame->f_code->co_flags & CO_COROUTINE) { + msg = "coroutine raised StopIteration"; + } + } + else if ((frame->f_code->co_flags & CO_ASYNC_GENERATOR) && + PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) + { + /* code in `gen` raised a StopAsyncIteration error: + raise a RuntimeError. + */ + msg = "async generator raised StopAsyncIteration"; + } + if (msg != NULL) { + PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg)); + if (message == NULL) { + goto error; + } + PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message); + if (error == NULL) { + Py_DECREF(message); + goto error; + } + assert(PyExceptionInstance_Check(error)); + SET_TOP(error); + PyException_SetCause(error, exc); + Py_INCREF(exc); + PyException_SetContext(error, exc); + Py_DECREF(message); + } + DISPATCH(); + } + + // stack effect: ( -- __0) inst(LOAD_ASSERTION_ERROR) { PyObject *value = PyExc_AssertionError; |