bpo-45123: PyAiter_Check and PyObject_GetAiter fix & rename. (GH-28194) Fix PyAiter_Check to only check for the `__anext__` presense (not for `__aiter__`). Rename `PyAiter_Check()` to `PyAIter_Check()`, `PyObject_GetAiter()` -> `PyObject_GetAIter()`. Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index 63290e0..f7106f4 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst
@@ -12,7 +12,7 @@ Return non-zero if the object *o* supports the iterator protocol, and ``0`` otherwise. This function always succeeds. -.. c:function:: int PyAiter_Check(PyObject *o) +.. c:function:: int PyAIter_Check(PyObject *o) Returns non-zero if the object 'obj' provides :class:`AsyncIterator` protocols, and ``0`` otherwise. This function always succeeds.
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 70cff69..17e3707 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst
@@ -358,7 +358,7 @@ iterated. -.. c:function:: PyObject* PyObject_GetAiter(PyObject *o) +.. c:function:: PyObject* PyObject_GetAIter(PyObject *o) This is the equivalent to the Python expression ``aiter(o)``. Takes an :class:`AsyncIterable` object and returns an :class:`AsyncIterator` for it.
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 3ef1b28..1694cad 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat
@@ -1073,8 +1073,8 @@ PyIter_Check:int::: PyIter_Check:PyObject*:o:0: -PyAiter_Check:int::: -PyAiter_Check:PyObject*:o:0: +PyAIter_Check:int::: +PyAIter_Check:PyObject*:o:0: PyIter_Next:PyObject*::+1: PyIter_Next:PyObject*:o:0: @@ -1700,8 +1700,8 @@ PyObject_GetIter:PyObject*::+1: PyObject_GetIter:PyObject*:o:0: -PyObject_GetAiter:PyObject*::+1: -PyObject_GetAiter:PyObject*:o:0: +PyObject_GetAIter:PyObject*::+1: +PyObject_GetAIter:PyObject*:o:0: PyObject_HasAttr:int::: PyObject_HasAttr:PyObject*:o:0:
diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index ea57cc8..b41027d 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat
@@ -1,5 +1,5 @@ role,name,added,ifdef_note -function,PyAiter_Check,3.10, +function,PyAIter_Check,3.10, function,PyArg_Parse,3.2, function,PyArg_ParseTuple,3.2, function,PyArg_ParseTupleAndKeywords,3.2, @@ -491,7 +491,7 @@ function,PyObject_GenericGetDict,3.10, function,PyObject_GenericSetAttr,3.2, function,PyObject_GenericSetDict,3.7, -function,PyObject_GetAiter,3.10, +function,PyObject_GetAIter,3.10, function,PyObject_GetAttr,3.2, function,PyObject_GetAttrString,3.2, function,PyObject_GetItem,3.2,
diff --git a/Include/abstract.h b/Include/abstract.h index 929861e..e8d3f92 100644 --- a/Include/abstract.h +++ b/Include/abstract.h
@@ -374,7 +374,7 @@ PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); /* Takes an AsyncIterable object and returns an AsyncIterator for it. This is typically a new iterator but if the argument is an AsyncIterator, this returns itself. */ -PyAPI_FUNC(PyObject *) PyObject_GetAiter(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_GetAIter(PyObject *); /* Returns non-zero if the object 'obj' provides iterator protocols, and 0 otherwise. @@ -384,7 +384,7 @@ PyAPI_FUNC(int) PyIter_Check(PyObject *); /* Returns non-zero if the object 'obj' provides AsyncIterator protocols, and 0 otherwise. This function always succeeds. */ -PyAPI_FUNC(int) PyAiter_Check(PyObject *); +PyAPI_FUNC(int) PyAIter_Check(PyObject *); /* Takes an iterator object and calls its tp_iternext slot, returning the next value.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-09-06-21-52-45.bpo-45123.8Eh9iI.rst b/Misc/NEWS.d/next/Core and Builtins/2021-09-06-21-52-45.bpo-45123.8Eh9iI.rst new file mode 100644 index 0000000..6cc7303 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-09-06-21-52-45.bpo-45123.8Eh9iI.rst
@@ -0,0 +1,3 @@ +Fix PyAiter_Check to only check for the __anext__ presence (not for +__aiter__). Rename PyAiter_Check to PyAIter_Check, PyObject_GetAiter -> +PyObject_GetAIter.
diff --git a/Misc/stable_abi.txt b/Misc/stable_abi.txt index a3ee0f0..72fa426 100644 --- a/Misc/stable_abi.txt +++ b/Misc/stable_abi.txt
@@ -2110,9 +2110,9 @@ function _Py_DecRef added 3.10 abi_only -function PyAiter_Check +function PyAIter_Check added 3.10 -function PyObject_GetAiter +function PyObject_GetAIter added 3.10 data PyExc_EncodingWarning added 3.10
diff --git a/Objects/abstract.c b/Objects/abstract.c index 8ad1910..33eb857 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c
@@ -2816,18 +2816,18 @@ PyObject_GetIter(PyObject *o) } PyObject * -PyObject_GetAiter(PyObject *o) { +PyObject_GetAIter(PyObject *o) { PyTypeObject *t = Py_TYPE(o); unaryfunc f; if (t->tp_as_async == NULL || t->tp_as_async->am_aiter == NULL) { - return type_error("'%.200s' object is not an AsyncIterable", o); + return type_error("'%.200s' object is not an async iterable", o); } f = t->tp_as_async->am_aiter; PyObject *it = (*f)(o); - if (it != NULL && !PyAiter_Check(it)) { + if (it != NULL && !PyAIter_Check(it)) { PyErr_Format(PyExc_TypeError, - "aiter() returned non-AsyncIterator of type '%.100s'", + "aiter() returned not an async iterator of type '%.100s'", Py_TYPE(it)->tp_name); Py_DECREF(it); it = NULL; @@ -2844,12 +2844,10 @@ PyIter_Check(PyObject *obj) } int -PyAiter_Check(PyObject *obj) +PyAIter_Check(PyObject *obj) { PyTypeObject *tp = Py_TYPE(obj); return (tp->tp_as_async != NULL && - tp->tp_as_async->am_aiter != NULL && - tp->tp_as_async->am_aiter != &_PyObject_NextNotImplemented && tp->tp_as_async->am_anext != NULL && tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented); }
diff --git a/PC/python3dll.c b/PC/python3dll.c index 2420e53..49b51e6 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c
@@ -86,7 +86,7 @@ EXPORT_FUNC(Py_SetPythonHome) EXPORT_FUNC(Py_SetRecursionLimit) EXPORT_FUNC(Py_VaBuildValue) EXPORT_FUNC(Py_XNewRef) -EXPORT_FUNC(PyAiter_Check) +EXPORT_FUNC(PyAIter_Check) EXPORT_FUNC(PyArg_Parse) EXPORT_FUNC(PyArg_ParseTuple) EXPORT_FUNC(PyArg_ParseTupleAndKeywords) @@ -443,7 +443,7 @@ EXPORT_FUNC(PyObject_GenericGetAttr) EXPORT_FUNC(PyObject_GenericGetDict) EXPORT_FUNC(PyObject_GenericSetAttr) EXPORT_FUNC(PyObject_GenericSetDict) -EXPORT_FUNC(PyObject_GetAiter) +EXPORT_FUNC(PyObject_GetAIter) EXPORT_FUNC(PyObject_GetAttr) EXPORT_FUNC(PyObject_GetAttrString) EXPORT_FUNC(PyObject_GetItem)
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 761dc08..7354183 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c
@@ -1610,7 +1610,7 @@ static PyObject * builtin_aiter(PyObject *module, PyObject *async_iterable) /*[clinic end generated code: output=1bae108d86f7960e input=473993d0cacc7d23]*/ { - return PyObject_GetAiter(async_iterable); + return PyObject_GetAIter(async_iterable); } PyObject *PyAnextAwaitable_New(PyObject *, PyObject *);