diff -r cca2ed4e8b41 Lib/test/test_coroutines.py --- a/Lib/test/test_coroutines.py Thu Dec 17 10:35:05 2015 +0000 +++ b/Lib/test/test_coroutines.py Thu Dec 17 12:59:00 2015 -0500 @@ -569,6 +569,63 @@ "coroutine ignored GeneratorExit"): c.close() + def test_func_15(self): + # See http://bugs.python.org/issue25887 for details + + async def send(): + return 'spam' + async def reader(coro): + return await coro + + spammer = send() + + with self.assertRaisesRegex(StopIteration, 'spam'): + reader(spammer).send(None) + + with self.assertRaisesRegex(RuntimeError, + 'coroutine was already awaited'): + reader(spammer).send(None) + + def test_func_16(self): + # See http://bugs.python.org/issue25887 for details + + @types.coroutine + def nop(): + yield + async def send(): + await nop() + return 'spam' + async def read(coro): + await nop() + return await coro + + spammer = send() + + reader = read(spammer) + reader.send(None) + reader.send(None) + with self.assertRaisesRegex(Exception, 'ham'): + reader.throw(Exception('ham')) + + reader = read(spammer) + reader.send(None) + with self.assertRaisesRegex(RuntimeError, + 'coroutine was already awaited'): + reader.send(None) + + def test_func_17(self): + # See http://bugs.python.org/issue25887 for details + async def coroutine(): + return 'spam' + + coro = coroutine() + with self.assertRaisesRegex(StopIteration, 'spam'): + coro.send(None) + + with self.assertRaisesRegex(RuntimeError, + 'coroutine was already awaited'): + coro.send(None) + def test_cr_await(self): @types.coroutine def a(): diff -r cca2ed4e8b41 Objects/genobject.c --- a/Objects/genobject.c Thu Dec 17 10:35:05 2015 +0000 +++ b/Objects/genobject.c Thu Dec 17 12:59:00 2015 -0500 @@ -93,8 +93,16 @@ } if (f == NULL || f->f_stacktop == NULL) { /* Only set exception if called from send() */ - if (arg && !exc) - PyErr_SetNone(PyExc_StopIteration); + if (arg && !exc) { + if (PyCoro_CheckExact(gen)) { + PyErr_SetString( + PyExc_RuntimeError, + "coroutine was already awaited"); + } else { + /* This is expected behaviour for generators */ + PyErr_SetNone(PyExc_StopIteration); + } + } return NULL; }