Skip to content

Commit 1010e3b

Browse files
committed
bpo-44963: Implement send() and throw() methods for anext_awaitable objects
1 parent 7903a10 commit 1010e3b

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

Lib/test/test_asyncgen.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import inspect
22
import types
33
import unittest
4+
import contextlib
45

56
from test.support.import_helper import import_module
67
asyncio = import_module("asyncio")
@@ -405,6 +406,26 @@ async def test_2():
405406
result = self.loop.run_until_complete(test_2())
406407
self.assertEqual(result, "completed")
407408

409+
def test_send():
410+
p = ait_class()
411+
obj = anext(p, "completed")
412+
try:
413+
with contextlib.closing(obj.__await__()) as g:
414+
g.send(None)
415+
except StopIteration:
416+
pass
417+
418+
test_send()
419+
420+
async def test_throw():
421+
p = ait_class()
422+
obj = anext(p, "completed")
423+
self.assertRaises(SyntaxError, obj.throw, SyntaxError)
424+
return "completed"
425+
426+
result = self.loop.run_until_complete(test_throw())
427+
self.assertEqual(result, "completed")
428+
408429
def test_async_generator_anext(self):
409430
async def agen():
410431
yield 1
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Implement ``send()`` and ``throw()`` methods for ``anext_awaitable``
2+
objects. Patch by Pablo Galindo.

Objects/iterobject.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,47 @@ anextawaitable_iternext(anextawaitableobject *obj)
371371
return NULL;
372372
}
373373

374+
375+
static PyObject *
376+
anextawaitable_send(anextawaitableobject *obj, PyObject *arg) {
377+
return PyObject_CallMethod(obj->wrapped, "send", "O", arg);
378+
}
379+
380+
381+
static PyObject *
382+
anextawaitable_throw(anextawaitableobject *obj, PyObject *arg) {
383+
return PyObject_CallMethod(obj->wrapped, "throw", "O", arg);
384+
}
385+
386+
387+
static PyObject *
388+
anextawaitable_close(anextawaitableobject *obj, PyObject *arg) {
389+
return PyObject_CallMethod(obj->wrapped, "close", "O", arg);
390+
}
391+
392+
393+
PyDoc_STRVAR(send_doc,
394+
"send(arg) -> send 'arg' into the wrapped iterator,\n\
395+
return next yielded value or raise StopIteration.");
396+
397+
398+
PyDoc_STRVAR(throw_doc,
399+
"throw(typ[,val[,tb]]) -> raise exception in the wrapped iterator,\n\
400+
return next yielded value or raise StopIteration.");
401+
402+
403+
PyDoc_STRVAR(close_doc,
404+
"close() -> raise GeneratorExit inside generator.");
405+
406+
407+
static PyMethodDef anextawaitable_methods[] = {
408+
{"send",(PyCFunction)anextawaitable_send, METH_O, send_doc},
409+
{"throw",(PyCFunction)anextawaitable_throw, METH_VARARGS, throw_doc},
410+
{"close",(PyCFunction)anextawaitable_close, METH_VARARGS, close_doc},
411+
{NULL, NULL} /* Sentinel */
412+
};
413+
414+
374415
static PyAsyncMethods anextawaitable_as_async = {
375416
PyObject_SelfIter, /* am_await */
376417
0, /* am_aiter */
@@ -407,7 +448,7 @@ PyTypeObject _PyAnextAwaitable_Type = {
407448
0, /* tp_weaklistoffset */
408449
PyObject_SelfIter, /* tp_iter */
409450
(unaryfunc)anextawaitable_iternext, /* tp_iternext */
410-
0, /* tp_methods */
451+
anextawaitable_methods, /* tp_methods */
411452
};
412453

413454
PyObject *

0 commit comments

Comments
 (0)