From c3b318e2d6252b5b579e878fc3a7c688ca424b3c Mon Sep 17 00:00:00 2001 From: johnslavik Date: Sat, 7 Mar 2026 18:58:42 +0100 Subject: [PATCH] Fix `async yield from` on non-iterator iterable objects in async gens --- Objects/genobject.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Objects/genobject.c b/Objects/genobject.c index 918c41da2aa846..5d4baec08b688a 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -2716,24 +2716,23 @@ PyTypeObject _PyAsyncGenYieldFrom_Type = { PyObject * -_PyAsyncGenYieldFrom_New(PyThreadState *tstate, PyObject *iterator) +_PyAsyncGenYieldFrom_New(PyThreadState *tstate, PyObject *iterable) { assert(tstate != NULL); - assert(iterator != NULL); + assert(iterable != NULL); _PyAsyncGenYieldFrom *yield_from = PyObject_GC_New(_PyAsyncGenYieldFrom, &_PyAsyncGenYieldFrom_Type); if (yield_from == NULL) { return NULL; } - if (!PyIter_Check(iterator)) { - if (PyAsyncGen_CheckExact(iterator)) { - _PyErr_Format(tstate, PyExc_TypeError, - "%T object is not iterable. Did you mean 'async yield from'?", - iterator); - } else { - _PyErr_Format(tstate, PyExc_TypeError, - "%T object is not iterable", iterator); - } + if (!Py_TYPE(iterable)->tp_iter && PyAsyncGen_CheckExact(iterable)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%T object is not iterable. Did you mean 'async yield from'?", + iterable); + return NULL; + } + PyObject *iterator = PyObject_GetIter(iterable); + if (iterator == NULL) { return NULL; } yield_from->agyf_iterator = Py_NewRef(iterator);