https://github.com/python/cpython/commit/cb12c5e514e378ef4e75a3402d2eff1162a321c5
commit: cb12c5e514e378ef4e75a3402d2eff1162a321c5
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-10-20T15:33:36+05:30
summary:

gh-157361: Implement `aiter()` in Python instead of C (#157687)

gh-157361: Implement aiter() in Python instead of C

Move both forms of aiter() into the frozen _pybuiltins module and remove
the C async_callable_iterator types. The callable form now returns an
iterator whose __anext__() is a plain coroutine, so call-graph tools can
see through it into the awaited result of the callable.

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-09-13-10-00-00.gh-issue-157361.aiterpy.rst
M Include/internal/pycore_interp_structs.h
M Include/internal/pycore_iterobject.h
M Lib/_pybuiltins.py
M Lib/test/test_asyncio/test_graph.py
M Lib/test/test_inspect/test_inspect.py
M Objects/iterobject.c
M Objects/object.c
M Python/bltinmodule.c
M Python/clinic/bltinmodule.c.h
M Tools/c-analyzer/cpython/globals-to-fix.tsv

diff --git a/Include/internal/pycore_interp_structs.h 
b/Include/internal/pycore_interp_structs.h
index dca86dec8be7979..a9ad61f458944ab 100644
--- a/Include/internal/pycore_interp_structs.h
+++ b/Include/internal/pycore_interp_structs.h
@@ -538,7 +538,7 @@ struct _py_func_state {
    If you add a new static type to the standard library, you may have to
    update one of these numbers.
    */
-#define _Py_NUM_MANAGED_PREINITIALIZED_TYPES 122
+#define _Py_NUM_MANAGED_PREINITIALIZED_TYPES 120
 #define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES \
     (_Py_NUM_MANAGED_PREINITIALIZED_TYPES + 83)
 #define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10
diff --git a/Include/internal/pycore_iterobject.h 
b/Include/internal/pycore_iterobject.h
index 90b444976e2f19c..b02eaa83b535146 100644
--- a/Include/internal/pycore_iterobject.h
+++ b/Include/internal/pycore_iterobject.h
@@ -8,20 +8,12 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-extern PyTypeObject _PyACallIter_Type;
-extern PyTypeObject _PyACallIterAwaitable_Type;
-
 // Like PyCallIter_New(), but the iteration also stops when *callable* raises
 // an exception matching *stop_exc* (an exception class or a tuple of exception
 // classes).  *sentinel* can be NULL; NULL *stop_exc* means StopIteration.
 extern PyObject *_PyCallIter_NewEx(PyObject *callable, PyObject *sentinel,
                                    PyObject *stop_exc);
 
-// The asynchronous counterpart of _PyCallIter_NewEx(): the result of
-// *callable* is awaited, and NULL *stop_exc* means StopAsyncIteration.
-extern PyObject *_PyACallIter_New(PyObject *callable, PyObject *sentinel,
-                                  PyObject *stop_exc);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/Lib/_pybuiltins.py b/Lib/_pybuiltins.py
index 01da295f53d0c73..dfcbeb57d07ebfd 100644
--- a/Lib/_pybuiltins.py
+++ b/Lib/_pybuiltins.py
@@ -5,11 +5,96 @@
 copied into the ``builtins`` module.
 """
 
-__all__ = ['anext']
+__all__ = ['aiter', 'anext']
 
 _NOT_GIVEN = sentinel("_NOT_GIVEN")
 
 
+def aiter(object, /, stop_value=_NOT_GIVEN, *, stop_exception=_NOT_GIVEN):
+    """Return an AsyncIterator for an AsyncIterable object.
+
+    In the second form, the callable is called and its result is awaited
+    until it returns the stop value or raises the specified exception.
+    """
+    if stop_value is _NOT_GIVEN and stop_exception is _NOT_GIVEN:
+        cls = type(object)
+        try:
+            # Looked up on the type, like the C slot am_aiter.
+            aiter_method = cls.__aiter__
+        except AttributeError:
+            raise TypeError(
+                f"'{cls.__name__}' object is not an async iterable"
+            ) from None
+        iterator = aiter_method(object)
+        if not hasattr(type(iterator), '__anext__'):
+            raise TypeError(
+                f"{cls.__name__}.__aiter__() must return an async iterator, "
+                f"not {type(iterator).__name__}"
+            )
+        return iterator
+
+    if not callable(object):
+        raise TypeError("aiter(): the first argument must be callable")
+    if stop_exception is _NOT_GIVEN:
+        stop_exception = StopAsyncIteration
+    else:
+        # Like _PyEval_CheckExceptTypeValid(): an exception class or a tuple
+        # of exception classes.
+        if isinstance(stop_exception, tuple):
+            items = stop_exception
+        else:
+            items = (stop_exception,)
+        for item in items:
+            if not (isinstance(item, type) and issubclass(item, 
BaseException)):
+                raise TypeError(
+                    "catching classes that do not inherit from BaseException "
+                    "is not allowed"
+                )
+    return async_callable_iterator(object, stop_value, stop_exception)
+
+
+class async_callable_iterator:
+    """The asynchronous counterpart of callable_iterator.
+
+    The callable is called and its result is awaited for every
+    __anext__().
+    """
+
+    __slots__ = ('_callable', '_stop_value', '_stop_exception')
+    __module__ = 'builtins'
+
+    def __init__(self, callable, stop_value, stop_exception):
+        # _callable is set to None when the iterator is exhausted.
+        self._callable = callable
+        self._stop_value = stop_value
+        self._stop_exception = stop_exception
+
+    def __aiter__(self):
+        return self
+
+    async def __anext__(self):
+        callable = self._callable
+        if callable is None:
+            raise StopAsyncIteration
+        try:
+            value = await callable()
+        except self._stop_exception:
+            self._exhaust()
+            raise StopAsyncIteration from None
+        except (StopIteration, StopAsyncIteration) as exc:
+            raise RuntimeError(
+                f"callable raised {type(exc).__name__}") from exc
+        stop_value = self._stop_value
+        if stop_value is not _NOT_GIVEN and stop_value == value:
+            self._exhaust()
+            raise StopAsyncIteration
+        return value
+
+    def _exhaust(self):
+        self._callable = None
+        self._stop_value = _NOT_GIVEN
+
+
 def anext(async_iterator, default=_NOT_GIVEN, /):
     """Return the next item from the async iterator.
 
diff --git a/Lib/test/test_asyncio/test_graph.py 
b/Lib/test/test_asyncio/test_graph.py
index 1326ef50c149b0b..7f6e0cc477774e1 100644
--- a/Lib/test/test_asyncio/test_graph.py
+++ b/Lib/test/test_asyncio/test_graph.py
@@ -148,6 +148,45 @@ async def main():
             'async generator 
CallStackTestBase.test_stack_async_gen.<locals>.gen()',
             stack_for_gen_nested_call[1])
 
+    async def test_stack_anext(self):
+        # anext() without a default returns the __anext__() coroutine
+        # itself, so nothing is inserted between it and main().
+
+        loop = asyncio.get_running_loop()
+        blocker = loop.create_future()
+
+        async def inner():
+            await blocker
+
+        class AIter:
+            def __aiter__(self):
+                return self
+
+            async def __anext__(self):
+                await inner()
+                return 1
+
+        async def main():
+            await anext(AIter())
+
+        task = asyncio.create_task(main(), name='anext task')
+        await asyncio.sleep(0)
+        try:
+            stack = capture_test_stack(fut=task)
+        finally:
+            blocker.set_result(None)
+            await task
+
+        self.assertEqual(stack[0], [
+            'T<anext task>',
+            [
+                'a inner',
+                'a __anext__',
+                'a main',
+            ],
+            []
+        ])
+
     async def test_stack_anext_default(self):
         # anext() with a default wraps the awaitable in a coroutine, so the
         # call graph of a suspended task sees through it into __anext__().
@@ -188,6 +227,84 @@ async def main():
             []
         ])
 
+    async def test_stack_aiter(self):
+        # The one-argument form of aiter() returns the object's own
+        # iterator, so it adds no frame of its own to the call graph.
+
+        loop = asyncio.get_running_loop()
+        blocker = loop.create_future()
+
+        async def inner():
+            await blocker
+
+        class AIter:
+            def __aiter__(self):
+                return self
+
+            async def __anext__(self):
+                await inner()
+                return 1
+
+        async def main():
+            async for _ in aiter(AIter()):
+                break
+
+        task = asyncio.create_task(main(), name='aiter task')
+        await asyncio.sleep(0)
+        try:
+            stack = capture_test_stack(fut=task)
+        finally:
+            blocker.set_result(None)
+            await task
+
+        self.assertEqual(stack[0], [
+            'T<aiter task>',
+            [
+                'a inner',
+                'a __anext__',
+                'a main',
+            ],
+            []
+        ])
+
+    async def test_stack_aiter_callable(self):
+        # aiter(callable, ...) returns an iterator whose __anext__() is a
+        # coroutine, so the call graph of a suspended task sees through it
+        # into the awaited result of the callable.
+
+        loop = asyncio.get_running_loop()
+        blocker = loop.create_future()
+
+        async def inner():
+            await blocker
+
+        async def spam():
+            await inner()
+            return 1
+
+        async def main():
+            async for _ in aiter(spam, 1):
+                pass
+
+        task = asyncio.create_task(main(), name='aiter task')
+        await asyncio.sleep(0)
+        try:
+            stack = capture_test_stack(fut=task)
+        finally:
+            blocker.set_result(None)
+            await task
+
+        self.assertEqual(stack[0], [
+            'T<aiter task>',
+            [
+                'a inner',
+                'a spam',
+                'a __anext__',
+                'a main',
+            ],
+            []
+        ])
+
     def test_ag_frame_used_for_async_generator(self):
         # Regression test for gh-148736: the ag_await branch of
         # _build_graph_for_future must read ag_frame, not cr_frame.
diff --git a/Lib/test/test_inspect/test_inspect.py 
b/Lib/test/test_inspect/test_inspect.py
index 3f14a9e66226eaa..5a3aa3e43fb2b2d 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -6229,7 +6229,7 @@ def test_builtins_have_signatures(self):
         needs_groups = {"range", "slice", "getattr", "next"}
         no_signature |= needs_groups
         # These have unrepresentable parameter default values of NULL
-        unsupported_signature = {"aiter", "iter", "dir", "vars"}
+        unsupported_signature = {"iter", "dir", "vars"}
         # These need *args support in Argument Clinic
         needs_varargs = {"min", "max", "__build_class__"}
         no_signature |= needs_varargs
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-09-13-10-00-00.gh-issue-157361.aiterpy.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-13-10-00-00.gh-issue-157361.aiterpy.rst
new file mode 100644
index 000000000000000..b0a3c584da911fb
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-13-10-00-00.gh-issue-157361.aiterpy.rst
@@ -0,0 +1,5 @@
+Implement :func:`aiter` in Python instead of C, in the frozen ``_pybuiltins``
+module. The async iterator returned by ``aiter(callable, ...)`` now has a
+plain coroutine ``__anext__()``, so introspection tools such as
+:func:`asyncio.print_call_graph` can see through it into the awaited
+callable result.
diff --git a/Objects/iterobject.c b/Objects/iterobject.c
index 2d5e3709a27dfb0..fcef1cc9c301434 100644
--- a/Objects/iterobject.c
+++ b/Objects/iterobject.c
@@ -399,381 +399,3 @@ PyTypeObject PyCallIter_Type = {
     calliter_iternext,                          /* tp_iternext */
     calliter_methods,                           /* tp_methods */
 };
-
-
-/* -------------------------------------- */
-
-static PyObject *
-awaitable_getiter(PyObject *owner, PyObject *wrapped)
-{
-    assert(wrapped != NULL);
-    PyObject *awaitable = _PyCoro_GetAwaitableIter(wrapped);
-    if (awaitable == NULL) {
-        return NULL;
-    }
-    if (Py_TYPE(awaitable)->tp_iternext == NULL) {
-        /* _PyCoro_GetAwaitableIter returns a Coroutine, a Generator,
-         * or an iterator. Of these, only coroutines lack tp_iternext.
-         */
-        assert(PyCoro_CheckExact(awaitable));
-        unaryfunc getter = Py_TYPE(awaitable)->tp_as_async->am_await;
-        PyObject *new_awaitable = getter(awaitable);
-        if (new_awaitable == NULL) {
-            Py_DECREF(awaitable);
-            return NULL;
-        }
-        Py_SETREF(awaitable, new_awaitable);
-        if (!PyIter_Check(awaitable)) {
-            PyErr_Format(PyExc_TypeError,
-                         "%T.__await__() must return an iterable, not %T",
-                         owner, awaitable);
-            Py_DECREF(awaitable);
-            return NULL;
-        }
-    }
-    return awaitable;
-}
-
-
-PyDoc_STRVAR(send_doc,
-"send(arg) -> send 'arg' into the wrapped iterator,\n\
-return next yielded value or raise StopIteration.");
-
-
-PyDoc_STRVAR(throw_doc,
-"throw(value)\n\
-throw(typ[,val[,tb]])\n\
-\n\
-raise exception in the wrapped iterator, return next yielded value\n\
-or raise StopIteration.\n\
-the (type, val, tb) signature is deprecated, \n\
-and may be removed in a future version of Python.");
-
-
-PyDoc_STRVAR(close_doc,
-"close() -> raise GeneratorExit inside generator.");
-
-
-/* -------------------------------------- */
-
-/* The asynchronous counterpart of calliterobject: the callable is called
-   and its result is awaited for every __anext__(). */
-
-typedef struct {
-    PyObject_HEAD
-    PyObject *it_callable;  /* set to NULL when the iterator is exhausted */
-    PyObject *it_sentinel;  /* can be NULL, and is when exhausted */
-    PyObject *it_stop_exc;  /* never NULL */
-} acalliterobject;
-
-#define acalliterobject_CAST(op)        ((acalliterobject *)(op))
-
-/* The awaitable returned by acalliter_anext().  The callable is only
-   called when this object is awaited. */
-typedef struct {
-    PyObject_HEAD
-    PyObject *aw_iterator; /* the iterator which created this object */
-    PyObject *aw_wrapped;  /* the awaitable returned by the callable */
-    bool aw_closed;
-} acallawaitableobject;
-
-#define acallawaitableobject_CAST(op)   ((acallawaitableobject *)(op))
-
-PyObject *
-_PyACallIter_New(PyObject *callable, PyObject *sentinel, PyObject *stop_exc)
-{
-    if (stop_exc == NULL) {
-        stop_exc = PyExc_StopAsyncIteration;
-    }
-    else if (_PyEval_CheckExceptTypeValid(_PyThreadState_GET(), stop_exc) < 0) 
{
-        return NULL;
-    }
-    acalliterobject *it = PyObject_GC_New(acalliterobject, &_PyACallIter_Type);
-    if (it == NULL) {
-        return NULL;
-    }
-    it->it_callable = Py_NewRef(callable);
-    it->it_sentinel = Py_XNewRef(sentinel);
-    it->it_stop_exc = Py_NewRef(stop_exc);
-    _PyObject_GC_TRACK(it);
-    return (PyObject *)it;
-}
-
-static void
-acalliter_exhaust(acalliterobject *it)
-{
-    Py_CLEAR(it->it_callable);
-    Py_CLEAR(it->it_sentinel);
-}
-
-static void
-acalliter_dealloc(PyObject *op)
-{
-    acalliterobject *it = acalliterobject_CAST(op);
-    _PyObject_GC_UNTRACK(it);
-    Py_XDECREF(it->it_callable);
-    Py_XDECREF(it->it_sentinel);
-    Py_XDECREF(it->it_stop_exc);
-    PyObject_GC_Del(it);
-}
-
-static int
-acalliter_traverse(PyObject *op, visitproc visit, void *arg)
-{
-    acalliterobject *it = acalliterobject_CAST(op);
-    Py_VISIT(it->it_callable);
-    Py_VISIT(it->it_sentinel);
-    Py_VISIT(it->it_stop_exc);
-    return 0;
-}
-
-static PyObject *acallawaitable_new(PyObject *iterator);
-
-static PyObject *
-acalliter_anext(PyObject *op)
-{
-    return acallawaitable_new(op);
-}
-
-static PyAsyncMethods acalliter_as_async = {
-    0,                                          /* am_await */
-    PyObject_SelfIter,                          /* am_aiter */
-    acalliter_anext,                            /* am_anext */
-    0,                                          /* am_send  */
-};
-
-PyTypeObject _PyACallIter_Type = {
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    .tp_name = "async_callable_iterator",
-    .tp_basicsize = sizeof(acalliterobject),
-    .tp_dealloc = acalliter_dealloc,
-    .tp_as_async = &acalliter_as_async,
-    .tp_getattro = PyObject_GenericGetAttr,
-    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
-    .tp_traverse = acalliter_traverse,
-};
-
-/* -------------------------------------- */
-
-static PyObject *
-acallawaitable_new(PyObject *iterator)
-{
-    acallawaitableobject *aw = PyObject_GC_New(
-            acallawaitableobject, &_PyACallIterAwaitable_Type);
-    if (aw == NULL) {
-        return NULL;
-    }
-    aw->aw_iterator = Py_NewRef(iterator);
-    aw->aw_wrapped = NULL;
-    aw->aw_closed = false;
-    _PyObject_GC_TRACK(aw);
-    return (PyObject *)aw;
-}
-
-static void
-acallawaitable_dealloc(PyObject *op)
-{
-    acallawaitableobject *aw = acallawaitableobject_CAST(op);
-    _PyObject_GC_UNTRACK(aw);
-    Py_XDECREF(aw->aw_iterator);
-    Py_XDECREF(aw->aw_wrapped);
-    PyObject_GC_Del(aw);
-}
-
-static int
-acallawaitable_traverse(PyObject *op, visitproc visit, void *arg)
-{
-    acallawaitableobject *aw = acallawaitableobject_CAST(op);
-    Py_VISIT(aw->aw_iterator);
-    Py_VISIT(aw->aw_wrapped);
-    return 0;
-}
-
-/* Call the callable.  Return 0 on success, -1 on failure. */
-static int
-acallawaitable_start(acallawaitableobject *aw)
-{
-    acalliterobject *it = acalliterobject_CAST(aw->aw_iterator);
-
-    if (aw->aw_closed) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        "cannot reuse already awaited __anext__()");
-        return -1;
-    }
-    if (it->it_callable == NULL) {
-        PyErr_SetNone(PyExc_StopAsyncIteration);
-        return -1;
-    }
-    PyObject *awaitable = _PyObject_CallNoArgs(it->it_callable);
-    if (awaitable == NULL) {
-        if (PyErr_ExceptionMatches(it->it_stop_exc)) {
-            PyErr_Clear();
-            acalliter_exhaust(it);
-            PyErr_SetNone(PyExc_StopAsyncIteration);
-        }
-        else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
-            /* It would be mistaken for the result of the await (PEP 525). */
-            _PyErr_FormatFromCause(PyExc_RuntimeError,
-                                   "callable raised StopIteration");
-        }
-        else if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
-            /* It would be mistaken for the end of the iteration (PEP 525). */
-            _PyErr_FormatFromCause(PyExc_RuntimeError,
-                                   "callable raised StopAsyncIteration");
-        }
-        return -1;
-    }
-    aw->aw_wrapped = awaitable;
-    return 0;
-}
-
-/* Turn the exception raised by the wrapped awaitable into the result of
-   the await.  Always returns NULL. */
-static PyObject *
-acallawaitable_handle_error(acallawaitableobject *aw)
-{
-    acalliterobject *it = acalliterobject_CAST(aw->aw_iterator);
-
-    if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
-        PyObject *value;
-        if (_PyGen_FetchStopIterationValue(&value) < 0) {
-            return NULL;
-        }
-        int ok = 0;
-        if (it->it_sentinel != NULL) {
-            ok = PyObject_RichCompareBool(it->it_sentinel, value, Py_EQ);
-        }
-        if (ok == 0) {
-            (void)_PyGen_SetStopIterationValue(value);
-        }
-        else if (ok > 0) {
-            acalliter_exhaust(it);
-            PyErr_SetNone(PyExc_StopAsyncIteration);
-        }
-        Py_DECREF(value);
-        return NULL;
-    }
-    if (PyErr_ExceptionMatches(it->it_stop_exc)) {
-        PyErr_Clear();
-        acalliter_exhaust(it);
-        PyErr_SetNone(PyExc_StopAsyncIteration);
-    }
-    else if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
-        /* It would be mistaken for the end of the iteration (see PEP 525). */
-        _PyErr_FormatFromCause(PyExc_RuntimeError,
-                               "callable raised StopAsyncIteration");
-    }
-    return NULL;
-}
-
-static PyObject *
-acallawaitable_iternext(PyObject *op)
-{
-    acallawaitableobject *aw = acallawaitableobject_CAST(op);
-
-    if (aw->aw_wrapped == NULL && acallawaitable_start(aw) < 0) {
-        return NULL;
-    }
-    PyObject *awaitable = awaitable_getiter(op, aw->aw_wrapped);
-    if (awaitable == NULL) {
-        return NULL;
-    }
-    PyObject *result = (*Py_TYPE(awaitable)->tp_iternext)(awaitable);
-    Py_DECREF(awaitable);
-    if (result != NULL) {
-        return result;
-    }
-    return acallawaitable_handle_error(aw);
-}
-
-static PyObject *
-acallawaitable_proxy(acallawaitableobject *aw, char *meth, PyObject *arg)
-{
-    PyObject *awaitable = awaitable_getiter((PyObject *)aw, aw->aw_wrapped);
-    if (awaitable == NULL) {
-        return NULL;
-    }
-    // When specified, 'arg' may be a tuple (if coming from a METH_VARARGS
-    // method) or a single object (if coming from a METH_O method).
-    PyObject *ret = arg == NULL
-        ? PyObject_CallMethod(awaitable, meth, NULL)
-        : PyObject_CallMethod(awaitable, meth, "O", arg);
-    Py_DECREF(awaitable);
-    if (ret != NULL) {
-        return ret;
-    }
-    return acallawaitable_handle_error(aw);
-}
-
-static PyObject *
-acallawaitable_send(PyObject *op, PyObject *arg)
-{
-    acallawaitableobject *aw = acallawaitableobject_CAST(op);
-
-    if (aw->aw_wrapped == NULL && acallawaitable_start(aw) < 0) {
-        return NULL;
-    }
-    return acallawaitable_proxy(aw, "send", arg);
-}
-
-static PyObject *
-acallawaitable_throw(PyObject *op, PyObject *args)
-{
-    acallawaitableobject *aw = acallawaitableobject_CAST(op);
-
-    if (aw->aw_wrapped == NULL) {
-        /* Not started, so the exception is raised at the point of the
-           await, as for a not started coroutine. */
-        PyObject *typ, *val = NULL, *tb = NULL;
-        if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb)) {
-            return NULL;
-        }
-        aw->aw_closed = true;
-        (void)_PyGen_SetException(typ, val, tb);
-        return NULL;
-    }
-    return acallawaitable_proxy(aw, "throw", args);
-}
-
-static PyObject *
-acallawaitable_close(PyObject *op, PyObject *Py_UNUSED(dummy))
-{
-    acallawaitableobject *aw = acallawaitableobject_CAST(op);
-
-    if (aw->aw_wrapped == NULL) {
-        /* Not started, so there is nothing to close. */
-        aw->aw_closed = true;
-        Py_RETURN_NONE;
-    }
-    PyObject *result = acallawaitable_proxy(aw, "close", NULL);
-    aw->aw_closed = true;
-    return result;
-}
-
-static PyMethodDef acallawaitable_methods[] = {
-    {"send", acallawaitable_send, METH_O, send_doc},
-    {"throw", acallawaitable_throw, METH_VARARGS, throw_doc},
-    {"close", acallawaitable_close, METH_NOARGS, close_doc},
-    {NULL, NULL}        /* Sentinel */
-};
-
-static PyAsyncMethods acallawaitable_as_async = {
-    PyObject_SelfIter,                          /* am_await */
-    0,                                          /* am_aiter */
-    0,                                          /* am_anext */
-    0,                                          /* am_send  */
-};
-
-PyTypeObject _PyACallIterAwaitable_Type = {
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    .tp_name = "async_callable_iterator_awaitable",
-    .tp_basicsize = sizeof(acallawaitableobject),
-    .tp_dealloc = acallawaitable_dealloc,
-    .tp_as_async = &acallawaitable_as_async,
-    .tp_getattro = PyObject_GenericGetAttr,
-    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
-    .tp_traverse = acallawaitable_traverse,
-    .tp_iter = PyObject_SelfIter,
-    .tp_iternext = acallawaitable_iternext,
-    .tp_methods = acallawaitable_methods,
-};
diff --git a/Objects/object.c b/Objects/object.c
index e334097d31c4325..f8206e5d3eca329 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2533,8 +2533,6 @@ _PyObject_FiniState(PyInterpreterState *interp)
 }
 
 
-extern PyTypeObject _PyACallIter_Type;
-extern PyTypeObject _PyACallIterAwaitable_Type;
 extern PyTypeObject _PyLegacyEventHandler_Type;
 extern PyTypeObject _PyLineIterator;
 extern PyTypeObject _PyMemoryIter_Type;
@@ -2627,8 +2625,6 @@ static PyTypeObject* 
static_types[_Py_NUM_MANAGED_PREINITIALIZED_TYPES] = {
     &PyWrapperDescr_Type,
     &PyZip_Type,
     &Py_GenericAliasType,
-    &_PyACallIter_Type,
-    &_PyACallIterAwaitable_Type,
     &_PyAsyncGenASend_Type,
     &_PyAsyncGenAThrow_Type,
     &_PyAsyncGenWrappedValue_Type,
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 796897ff24cdc02..10c5428159e66f9 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1931,38 +1931,6 @@ builtin_iter_impl(PyObject *module, PyObject *object, 
PyObject *stop_value,
 }
 
 
-/*[clinic input]
-@text_signature "($module, object, /, [stop_value], *, 
stop_exception=StopAsyncIteration)"
-aiter as builtin_aiter
-
-    object: object
-    /
-    stop_value: object = NULL
-    *
-    stop_exception: object = NULL
-
-Return an AsyncIterator for an AsyncIterable object.
-
-In the second form, the callable is called and its result is awaited
-until it returns the stop value or raises the specified exception.
-[clinic start generated code]*/
-
-static PyObject *
-builtin_aiter_impl(PyObject *module, PyObject *object, PyObject *stop_value,
-                   PyObject *stop_exception)
-/*[clinic end generated code: output=2865edb3fbc45693 input=2adb37d12adafd0c]*/
-{
-    if (stop_value == NULL && stop_exception == NULL) {
-        return PyObject_GetAIter(object);
-    }
-    if (!PyCallable_Check(object)) {
-        PyErr_SetString(PyExc_TypeError,
-                        "aiter(): the first argument must be callable");
-        return NULL;
-    }
-    return _PyACallIter_New(object, stop_value, stop_exception);
-}
-
 /*[clinic input]
 len as builtin_len
 
@@ -3455,7 +3423,6 @@ static PyMethodDef builtin_methods[] = {
     BUILTIN_ISINSTANCE_METHODDEF
     BUILTIN_ISSUBCLASS_METHODDEF
     BUILTIN_ITER_METHODDEF
-    BUILTIN_AITER_METHODDEF
     BUILTIN_LEN_METHODDEF
     BUILTIN_LOCALS_METHODDEF
     {"max", _PyCFunction_CAST(builtin_max), METH_FASTCALL | METH_KEYWORDS, 
max_doc},
diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h
index 0a32ca28da2ef2d..bdb3dd560b39b8b 100644
--- a/Python/clinic/bltinmodule.c.h
+++ b/Python/clinic/bltinmodule.c.h
@@ -970,86 +970,6 @@ builtin_iter(PyObject *module, PyObject *const *args, 
Py_ssize_t nargs, PyObject
     return return_value;
 }
 
-PyDoc_STRVAR(builtin_aiter__doc__,
-"aiter($module, object, /, [stop_value], *, 
stop_exception=StopAsyncIteration)\n"
-"--\n"
-"\n"
-"Return an AsyncIterator for an AsyncIterable object.\n"
-"\n"
-"In the second form, the callable is called and its result is awaited\n"
-"until it returns the stop value or raises the specified exception.");
-
-#define BUILTIN_AITER_METHODDEF    \
-    {"aiter", _PyCFunction_CAST(builtin_aiter), METH_FASTCALL|METH_KEYWORDS, 
builtin_aiter__doc__},
-
-static PyObject *
-builtin_aiter_impl(PyObject *module, PyObject *object, PyObject *stop_value,
-                   PyObject *stop_exception);
-
-static PyObject *
-builtin_aiter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, 
PyObject *kwnames)
-{
-    PyObject *return_value = NULL;
-    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
-
-    #define NUM_KEYWORDS 2
-    static struct {
-        PyGC_Head _this_is_not_used;
-        PyObject_VAR_HEAD
-        Py_hash_t ob_hash;
-        PyObject *ob_item[NUM_KEYWORDS];
-    } _kwtuple = {
-        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
-        .ob_hash = -1,
-        .ob_item = { &_Py_ID(stop_value), &_Py_ID(stop_exception), },
-    };
-    #undef NUM_KEYWORDS
-    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
-
-    #else  // !Py_BUILD_CORE
-    #  define KWTUPLE NULL
-    #endif  // !Py_BUILD_CORE
-
-    static const char * const _keywords[] = {"", "stop_value", 
"stop_exception", NULL};
-    static _PyArg_Parser _parser = {
-        .keywords = _keywords,
-        .fname = "aiter",
-        .kwtuple = KWTUPLE,
-    };
-    #undef KWTUPLE
-    PyObject *argsbuf[3];
-    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 
1;
-    PyObject *object;
-    PyObject *stop_value = NULL;
-    PyObject *stop_exception = NULL;
-
-    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
-            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
-    if (!args) {
-        goto exit;
-    }
-    object = args[0];
-    if (!noptargs) {
-        goto skip_optional_pos;
-    }
-    if (args[1]) {
-        stop_value = args[1];
-        if (!--noptargs) {
-            goto skip_optional_pos;
-        }
-    }
-skip_optional_pos:
-    if (!noptargs) {
-        goto skip_optional_kwonly;
-    }
-    stop_exception = args[2];
-skip_optional_kwonly:
-    return_value = builtin_aiter_impl(module, object, stop_value, 
stop_exception);
-
-exit:
-    return return_value;
-}
-
 PyDoc_STRVAR(builtin_len__doc__,
 "len($module, obj, /)\n"
 "--\n"
@@ -1575,4 +1495,4 @@ builtin_issubclass(PyObject *module, PyObject *const 
*args, Py_ssize_t nargs)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=ac4800dc25f87f6e input=a9049054013a1b77]*/
+/*[clinic end generated code: output=1dacff294aaa7485 input=a9049054013a1b77]*/
diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv 
b/Tools/c-analyzer/cpython/globals-to-fix.tsv
index 67ced170243e4a2..251af27908cfc38 100644
--- a/Tools/c-analyzer/cpython/globals-to-fix.tsv
+++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv
@@ -58,8 +58,6 @@ Objects/genobject.c   -       _PyCoroWrapper_Type     -
 Objects/interpolationobject.c  -       _PyInterpolation_Type   -
 Objects/iterobject.c   -       PyCallIter_Type -
 Objects/iterobject.c   -       PySeqIter_Type  -
-Objects/iterobject.c   -       _PyACallIter_Type       -
-Objects/iterobject.c   -       _PyACallIterAwaitable_Type      -
 Objects/lazyimportobject.c     -       PyLazyImport_Type       -
 Objects/listobject.c   -       PyListIter_Type -
 Objects/listobject.c   -       PyListRevIter_Type      -
@@ -74,8 +72,6 @@ Objects/moduleobject.c        -       PyModule_Type   -
 Objects/namespaceobject.c      -       _PyNamespace_Type       -
 Objects/object.c       -       _PyNone_Type    -
 Objects/object.c       -       _PyNotImplemented_Type  -
-Objects/object.c       -       _PyACallIter_Type       -
-Objects/object.c       -       _PyACallIterAwaitable_Type      -
 Objects/odictobject.c  -       PyODictItems_Type       -
 Objects/odictobject.c  -       PyODictIter_Type        -
 Objects/odictobject.c  -       PyODictKeys_Type        -

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to