PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);
PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
PyObject *_PyGen_Send(PyGenObject *, PyObject *);
+PyObject *_PyGen_yf(PyGenObject *);
PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self);
#ifndef Py_LIMITED_API
with self.assertRaises(Marker):
c.throw(ZeroDivisionError)
+ def test_await_15(self):
+ @types.coroutine
+ def nop():
+ yield
+
+ async def coroutine():
+ await nop()
+
+ async def waiter(coro):
+ await coro
+
+ coro = coroutine()
+ coro.send(None)
+
+ with self.assertRaisesRegex(RuntimeError,
+ "coroutine is being awaited already"):
+ waiter(coro).send(None)
+
def test_with_1(self):
class Manager:
def __init__(self, name):
return 0;
}
-static PyObject *
-gen_yf(PyGenObject *gen)
+PyObject *
+_PyGen_yf(PyGenObject *gen)
{
PyObject *yf = NULL;
PyFrameObject *f = gen->gi_frame;
gen_close(PyGenObject *gen, PyObject *args)
{
PyObject *retval;
- PyObject *yf = gen_yf(gen);
+ PyObject *yf = _PyGen_yf(gen);
int err = 0;
if (yf) {
PyObject *typ;
PyObject *tb = NULL;
PyObject *val = NULL;
- PyObject *yf = gen_yf(gen);
+ PyObject *yf = _PyGen_yf(gen);
_Py_IDENTIFIER(throw);
if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
static PyObject *
gen_getyieldfrom(PyGenObject *gen)
{
- PyObject *yf = gen_yf(gen);
+ PyObject *yf = _PyGen_yf(gen);
if (yf == NULL)
Py_RETURN_NONE;
return yf;
static PyObject *
coro_get_cr_await(PyCoroObject *coro)
{
- PyObject *yf = gen_yf((PyGenObject *) coro);
+ PyObject *yf = _PyGen_yf((PyGenObject *) coro);
if (yf == NULL)
Py_RETURN_NONE;
return yf;
Py_DECREF(iterable);
+ if (iter != NULL && PyCoro_CheckExact(iter)) {
+ PyObject *yf = _PyGen_yf((PyGenObject*)iter);
+ if (yf != NULL) {
+ /* `iter` is a coroutine object that is being
+ awaited, `yf` is a pointer to the current awaitable
+ being awaited on. */
+ Py_DECREF(yf);
+ Py_CLEAR(iter);
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "coroutine is being awaited already");
+ /* The code below jumps to `error` if `iter` is NULL. */
+ }
+ }
+
SET_TOP(iter); /* Even if it's NULL */
if (iter == NULL) {