From a4c728e6b36400ce9a6da39f5991702760b4052f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 24 Mar 2025 14:55:31 +0100 Subject: [PATCH 1/3] fix signature of `anext_awaitable.close` --- Lib/test/test_coroutines.py | 11 +++++++++++ Objects/iterobject.c | 10 ++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index ae3cd3555002ef..d78eaaca2796a6 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1191,6 +1191,17 @@ async def g(): _, result = run_async(g()) self.assertIsNone(result.__context__) + def test_await_17(self): + # See https://github.com/python/cpython/issues/131666 for details. + class A: + async def __anext__(self): + raise StopAsyncIteration + def __aiter__(self): + return self + + anext_awaitable = anext(A(), "a").__await__() + self.assertRaises(TypeError, anext_awaitable.close, 1) + def test_with_1(self): class Manager: def __init__(self, name): diff --git a/Objects/iterobject.c b/Objects/iterobject.c index c023f41638f3d3..3291b3898a8f11 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -408,7 +408,9 @@ anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) { if (awaitable == NULL) { return NULL; } - PyObject *ret = PyObject_CallMethod(awaitable, meth, "O", arg); + PyObject *ret = arg == NULL + ? PyObject_CallMethod(awaitable, meth, NULL) + : PyObject_CallMethod(awaitable, meth, "O", arg); Py_DECREF(awaitable); if (ret != NULL) { return ret; @@ -439,8 +441,8 @@ anextawaitable_throw(anextawaitableobject *obj, PyObject *arg) { static PyObject * -anextawaitable_close(anextawaitableobject *obj, PyObject *arg) { - return anextawaitable_proxy(obj, "close", arg); +anextawaitable_close(anextawaitableobject *obj, PyObject *Py_UNUSED(dummy)) { + return anextawaitable_proxy(obj, "close", NULL); } @@ -466,7 +468,7 @@ PyDoc_STRVAR(close_doc, static PyMethodDef anextawaitable_methods[] = { {"send",(PyCFunction)anextawaitable_send, METH_O, send_doc}, {"throw",(PyCFunction)anextawaitable_throw, METH_VARARGS, throw_doc}, - {"close",(PyCFunction)anextawaitable_close, METH_VARARGS, close_doc}, + {"close",(PyCFunction)anextawaitable_close, METH_NOARGS, close_doc}, {NULL, NULL} /* Sentinel */ }; From f8bac51de5843de6350e18991a6d2e86f8342d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 24 Mar 2025 14:56:07 +0100 Subject: [PATCH 2/3] blurb --- .../2025-03-24-14-56-00.gh-issue-131666.q0-a-b.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-03-24-14-56-00.gh-issue-131666.q0-a-b.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-03-24-14-56-00.gh-issue-131666.q0-a-b.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-24-14-56-00.gh-issue-131666.q0-a-b.rst new file mode 100644 index 00000000000000..45ac86e520d929 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-24-14-56-00.gh-issue-131666.q0-a-b.rst @@ -0,0 +1 @@ +Fix signature of ``anext_awaitable.close`` objects. Patch by Bénédikt Tran. From da35c4ef7b98678f1bb681238a15df375c067c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 24 Mar 2025 15:55:35 +0100 Subject: [PATCH 3/3] update comment --- Objects/iterobject.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Objects/iterobject.c b/Objects/iterobject.c index dddf8f20f78eb5..5712e02ae828ab 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -414,6 +414,8 @@ anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) 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);