Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d2dc15b

Browse files
committed
Merge 3.5 (issue #25888)
2 parents 5604446 + c724bae commit d2dc15b

4 files changed

Lines changed: 40 additions & 6 deletions

File tree

Include/genobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(struct _frame *,
4343
PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);
4444
PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
4545
PyObject *_PyGen_Send(PyGenObject *, PyObject *);
46+
PyObject *_PyGen_yf(PyGenObject *);
4647
PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self);
4748

4849
#ifndef Py_LIMITED_API

Lib/test/test_coroutines.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,24 @@ async def coro2():
942942
with self.assertRaises(Marker):
943943
c.throw(ZeroDivisionError)
944944

945+
def test_await_15(self):
946+
@types.coroutine
947+
def nop():
948+
yield
949+
950+
async def coroutine():
951+
await nop()
952+
953+
async def waiter(coro):
954+
await coro
955+
956+
coro = coroutine()
957+
coro.send(None)
958+
959+
with self.assertRaisesRegex(RuntimeError,
960+
"coroutine is being awaited already"):
961+
waiter(coro).send(None)
962+
945963
def test_with_1(self):
946964
class Manager:
947965
def __init__(self, name):

Objects/genobject.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ gen_close_iter(PyObject *yf)
267267
return 0;
268268
}
269269

270-
static PyObject *
271-
gen_yf(PyGenObject *gen)
270+
PyObject *
271+
_PyGen_yf(PyGenObject *gen)
272272
{
273273
PyObject *yf = NULL;
274274
PyFrameObject *f = gen->gi_frame;
@@ -290,7 +290,7 @@ static PyObject *
290290
gen_close(PyGenObject *gen, PyObject *args)
291291
{
292292
PyObject *retval;
293-
PyObject *yf = gen_yf(gen);
293+
PyObject *yf = _PyGen_yf(gen);
294294
int err = 0;
295295

296296
if (yf) {
@@ -330,7 +330,7 @@ gen_throw(PyGenObject *gen, PyObject *args)
330330
PyObject *typ;
331331
PyObject *tb = NULL;
332332
PyObject *val = NULL;
333-
PyObject *yf = gen_yf(gen);
333+
PyObject *yf = _PyGen_yf(gen);
334334
_Py_IDENTIFIER(throw);
335335

336336
if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
@@ -556,7 +556,7 @@ gen_set_qualname(PyGenObject *op, PyObject *value)
556556
static PyObject *
557557
gen_getyieldfrom(PyGenObject *gen)
558558
{
559-
PyObject *yf = gen_yf(gen);
559+
PyObject *yf = _PyGen_yf(gen);
560560
if (yf == NULL)
561561
Py_RETURN_NONE;
562562
return yf;
@@ -791,7 +791,7 @@ coro_await(PyCoroObject *coro)
791791
static PyObject *
792792
coro_get_cr_await(PyCoroObject *coro)
793793
{
794-
PyObject *yf = gen_yf((PyGenObject *) coro);
794+
PyObject *yf = _PyGen_yf((PyGenObject *) coro);
795795
if (yf == NULL)
796796
Py_RETURN_NONE;
797797
return yf;

Python/ceval.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,6 +2021,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
20212021

20222022
Py_DECREF(iterable);
20232023

2024+
if (iter != NULL && PyCoro_CheckExact(iter)) {
2025+
PyObject *yf = _PyGen_yf((PyGenObject*)iter);
2026+
if (yf != NULL) {
2027+
/* `iter` is a coroutine object that is being
2028+
awaited, `yf` is a pointer to the current awaitable
2029+
being awaited on. */
2030+
Py_DECREF(yf);
2031+
Py_CLEAR(iter);
2032+
PyErr_SetString(
2033+
PyExc_RuntimeError,
2034+
"coroutine is being awaited already");
2035+
/* The code below jumps to `error` if `iter` is NULL. */
2036+
}
2037+
}
2038+
20242039
SET_TOP(iter); /* Even if it's NULL */
20252040

20262041
if (iter == NULL) {

0 commit comments

Comments
 (0)