bpo-31861: Add aiter and anext to builtins (#23847)

Co-authored-by: jab <jab@users.noreply.github.com>
Co-authored-by: Daniel Pope <mauve@mauveweb.co.uk>
Co-authored-by: Justin Wang <justin39@gmail.com>
This commit is contained in:
Joshua Bronson 2021-03-23 18:47:21 -04:00 committed by GitHub
parent 94faa0724f
commit f0a6fde882
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 373 additions and 28 deletions

View file

@ -1610,6 +1610,59 @@ supply its own iterator, or be a sequence.\n\
In the second form, the callable is called until it returns the sentinel.");
/*[clinic input]
aiter as builtin_aiter
async_iterable: object
/
Return an AsyncIterator for an AsyncIterable object.
[clinic start generated code]*/
static PyObject *
builtin_aiter(PyObject *module, PyObject *async_iterable)
/*[clinic end generated code: output=1bae108d86f7960e input=473993d0cacc7d23]*/
{
return PyObject_GetAiter(async_iterable);
}
PyObject *PyAnextAwaitable_New(PyObject *, PyObject *);
/*[clinic input]
anext as builtin_anext
aiterator: object
default: object = NULL
/
Return the next item from the async iterator.
[clinic start generated code]*/
static PyObject *
builtin_anext_impl(PyObject *module, PyObject *aiterator,
PyObject *default_value)
/*[clinic end generated code: output=f02c060c163a81fa input=699d11f4e38eca24]*/
{
PyTypeObject *t;
PyObject *awaitable;
t = Py_TYPE(aiterator);
if (t->tp_as_async == NULL || t->tp_as_async->am_anext == NULL) {
PyErr_Format(PyExc_TypeError,
"'%.200s' object is not an async iterator",
t->tp_name);
return NULL;
}
awaitable = (*t->tp_as_async->am_anext)(aiterator);
if (default_value == NULL) {
return awaitable;
}
return PyAnextAwaitable_New(awaitable, default_value);
}
/*[clinic input]
len as builtin_len
@ -2890,11 +2943,13 @@ static PyMethodDef builtin_methods[] = {
BUILTIN_ISINSTANCE_METHODDEF
BUILTIN_ISSUBCLASS_METHODDEF
{"iter", (PyCFunction)(void(*)(void))builtin_iter, METH_FASTCALL, iter_doc},
BUILTIN_AITER_METHODDEF
BUILTIN_LEN_METHODDEF
BUILTIN_LOCALS_METHODDEF
{"max", (PyCFunction)(void(*)(void))builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc},
{"min", (PyCFunction)(void(*)(void))builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc},
{"next", (PyCFunction)(void(*)(void))builtin_next, METH_FASTCALL, next_doc},
BUILTIN_ANEXT_METHODDEF
BUILTIN_OCT_METHODDEF
BUILTIN_ORD_METHODDEF
BUILTIN_POW_METHODDEF

View file

@ -530,6 +530,50 @@ PyDoc_STRVAR(builtin_hex__doc__,
#define BUILTIN_HEX_METHODDEF \
{"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__},
PyDoc_STRVAR(builtin_aiter__doc__,
"aiter($module, async_iterable, /)\n"
"--\n"
"\n"
"Return an AsyncIterator for an AsyncIterable object.");
#define BUILTIN_AITER_METHODDEF \
{"aiter", (PyCFunction)builtin_aiter, METH_O, builtin_aiter__doc__},
PyDoc_STRVAR(builtin_anext__doc__,
"anext($module, aiterator, default=<unrepresentable>, /)\n"
"--\n"
"\n"
"Return the next item from the async iterator.");
#define BUILTIN_ANEXT_METHODDEF \
{"anext", (PyCFunction)(void(*)(void))builtin_anext, METH_FASTCALL, builtin_anext__doc__},
static PyObject *
builtin_anext_impl(PyObject *module, PyObject *aiterator,
PyObject *default_value);
static PyObject *
builtin_anext(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject *aiterator;
PyObject *default_value = NULL;
if (!_PyArg_CheckPositional("anext", nargs, 1, 2)) {
goto exit;
}
aiterator = args[0];
if (nargs < 2) {
goto skip_optional;
}
default_value = args[1];
skip_optional:
return_value = builtin_anext_impl(module, aiterator, default_value);
exit:
return return_value;
}
PyDoc_STRVAR(builtin_len__doc__,
"len($module, obj, /)\n"
"--\n"
@ -830,4 +874,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
/*[clinic end generated code: output=e2fcf0201790367c input=a9049054013a1b77]*/
/*[clinic end generated code: output=da9ae459e9233259 input=a9049054013a1b77]*/