From f4adb975061874566766f7a67206cb7b0439bc11 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 3 Nov 2022 04:38:51 -0700 Subject: GH-96793: Implement PEP 479 in bytecode. (GH-99006) * Handle converting StopIteration to RuntimeError in bytecode. * Add custom instruction for converting StopIteration into RuntimeError. --- Python/bytecodes.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'Python/bytecodes.c') diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 94a4e7649d..b0d56279e0 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; -- cgit v1.2.1