summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-11-03 11:38:51 (GMT)
committerGitHub <noreply@github.com>2022-11-03 11:38:51 (GMT)
commitf4adb975061874566766f7a67206cb7b0439bc11 (patch)
tree136b2e8b97fd8811cef1d2ff46d31fb61f26183a /Python/bytecodes.c
parente9ac890c0273aee413aa528cc202c3efa29f1d7a (diff)
downloadcpython-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.c43
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;