mirror of https://github.com/python/cpython
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>
This commit is contained in:
parent
eb254b43d2
commit
2c3474a637
|
@ -12,7 +12,7 @@ There are two functions specifically for working with iterators.
|
||||||
Return non-zero if the object *o* supports the iterator protocol, and ``0``
|
Return non-zero if the object *o* supports the iterator protocol, and ``0``
|
||||||
otherwise. This function always succeeds.
|
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`
|
Returns non-zero if the object 'obj' provides :class:`AsyncIterator`
|
||||||
protocols, and ``0`` otherwise. This function always succeeds.
|
protocols, and ``0`` otherwise. This function always succeeds.
|
||||||
|
|
|
@ -358,7 +358,7 @@ Object Protocol
|
||||||
iterated.
|
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
|
This is the equivalent to the Python expression ``aiter(o)``. Takes an
|
||||||
:class:`AsyncIterable` object and returns an :class:`AsyncIterator` for it.
|
:class:`AsyncIterable` object and returns an :class:`AsyncIterator` for it.
|
||||||
|
|
|
@ -1073,8 +1073,8 @@ PyInterpreterState_New:PyInterpreterState*:::
|
||||||
PyIter_Check:int:::
|
PyIter_Check:int:::
|
||||||
PyIter_Check:PyObject*:o:0:
|
PyIter_Check:PyObject*:o:0:
|
||||||
|
|
||||||
PyAiter_Check:int:::
|
PyAIter_Check:int:::
|
||||||
PyAiter_Check:PyObject*:o:0:
|
PyAIter_Check:PyObject*:o:0:
|
||||||
|
|
||||||
PyIter_Next:PyObject*::+1:
|
PyIter_Next:PyObject*::+1:
|
||||||
PyIter_Next:PyObject*:o:0:
|
PyIter_Next:PyObject*:o:0:
|
||||||
|
@ -1700,8 +1700,8 @@ PyObject_GetItem:PyObject*:key:0:
|
||||||
PyObject_GetIter:PyObject*::+1:
|
PyObject_GetIter:PyObject*::+1:
|
||||||
PyObject_GetIter:PyObject*:o:0:
|
PyObject_GetIter:PyObject*:o:0:
|
||||||
|
|
||||||
PyObject_GetAiter:PyObject*::+1:
|
PyObject_GetAIter:PyObject*::+1:
|
||||||
PyObject_GetAiter:PyObject*:o:0:
|
PyObject_GetAIter:PyObject*:o:0:
|
||||||
|
|
||||||
PyObject_HasAttr:int:::
|
PyObject_HasAttr:int:::
|
||||||
PyObject_HasAttr:PyObject*:o:0:
|
PyObject_HasAttr:PyObject*:o:0:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
role,name,added,ifdef_note
|
role,name,added,ifdef_note
|
||||||
function,PyAiter_Check,3.10,
|
function,PyAIter_Check,3.10,
|
||||||
function,PyArg_Parse,3.2,
|
function,PyArg_Parse,3.2,
|
||||||
function,PyArg_ParseTuple,3.2,
|
function,PyArg_ParseTuple,3.2,
|
||||||
function,PyArg_ParseTupleAndKeywords,3.2,
|
function,PyArg_ParseTupleAndKeywords,3.2,
|
||||||
|
@ -491,7 +491,7 @@ function,PyObject_GenericGetAttr,3.2,
|
||||||
function,PyObject_GenericGetDict,3.10,
|
function,PyObject_GenericGetDict,3.10,
|
||||||
function,PyObject_GenericSetAttr,3.2,
|
function,PyObject_GenericSetAttr,3.2,
|
||||||
function,PyObject_GenericSetDict,3.7,
|
function,PyObject_GenericSetDict,3.7,
|
||||||
function,PyObject_GetAiter,3.10,
|
function,PyObject_GetAIter,3.10,
|
||||||
function,PyObject_GetAttr,3.2,
|
function,PyObject_GetAttr,3.2,
|
||||||
function,PyObject_GetAttrString,3.2,
|
function,PyObject_GetAttrString,3.2,
|
||||||
function,PyObject_GetItem,3.2,
|
function,PyObject_GetItem,3.2,
|
||||||
|
|
|
@ -374,7 +374,7 @@ PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *);
|
||||||
/* Takes an AsyncIterable object and returns an AsyncIterator for it.
|
/* Takes an AsyncIterable object and returns an AsyncIterator for it.
|
||||||
This is typically a new iterator but if the argument is an AsyncIterator,
|
This is typically a new iterator but if the argument is an AsyncIterator,
|
||||||
this returns itself. */
|
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.
|
/* 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.
|
/* Returns non-zero if the object 'obj' provides AsyncIterator protocols, and 0 otherwise.
|
||||||
|
|
||||||
This function always succeeds. */
|
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,
|
/* Takes an iterator object and calls its tp_iternext slot,
|
||||||
returning the next value.
|
returning the next value.
|
||||||
|
|
|
@ -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.
|
|
@ -2110,9 +2110,9 @@ function _Py_IncRef
|
||||||
function _Py_DecRef
|
function _Py_DecRef
|
||||||
added 3.10
|
added 3.10
|
||||||
abi_only
|
abi_only
|
||||||
function PyAiter_Check
|
function PyAIter_Check
|
||||||
added 3.10
|
added 3.10
|
||||||
function PyObject_GetAiter
|
function PyObject_GetAIter
|
||||||
added 3.10
|
added 3.10
|
||||||
data PyExc_EncodingWarning
|
data PyExc_EncodingWarning
|
||||||
added 3.10
|
added 3.10
|
||||||
|
|
|
@ -2816,18 +2816,18 @@ PyObject_GetIter(PyObject *o)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyObject_GetAiter(PyObject *o) {
|
PyObject_GetAIter(PyObject *o) {
|
||||||
PyTypeObject *t = Py_TYPE(o);
|
PyTypeObject *t = Py_TYPE(o);
|
||||||
unaryfunc f;
|
unaryfunc f;
|
||||||
|
|
||||||
if (t->tp_as_async == NULL || t->tp_as_async->am_aiter == NULL) {
|
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;
|
f = t->tp_as_async->am_aiter;
|
||||||
PyObject *it = (*f)(o);
|
PyObject *it = (*f)(o);
|
||||||
if (it != NULL && !PyAiter_Check(it)) {
|
if (it != NULL && !PyAIter_Check(it)) {
|
||||||
PyErr_Format(PyExc_TypeError,
|
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_TYPE(it)->tp_name);
|
||||||
Py_DECREF(it);
|
Py_DECREF(it);
|
||||||
it = NULL;
|
it = NULL;
|
||||||
|
@ -2844,12 +2844,10 @@ PyIter_Check(PyObject *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PyAiter_Check(PyObject *obj)
|
PyAIter_Check(PyObject *obj)
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = Py_TYPE(obj);
|
PyTypeObject *tp = Py_TYPE(obj);
|
||||||
return (tp->tp_as_async != NULL &&
|
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 != NULL &&
|
||||||
tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented);
|
tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ EXPORT_FUNC(Py_SetPythonHome)
|
||||||
EXPORT_FUNC(Py_SetRecursionLimit)
|
EXPORT_FUNC(Py_SetRecursionLimit)
|
||||||
EXPORT_FUNC(Py_VaBuildValue)
|
EXPORT_FUNC(Py_VaBuildValue)
|
||||||
EXPORT_FUNC(Py_XNewRef)
|
EXPORT_FUNC(Py_XNewRef)
|
||||||
EXPORT_FUNC(PyAiter_Check)
|
EXPORT_FUNC(PyAIter_Check)
|
||||||
EXPORT_FUNC(PyArg_Parse)
|
EXPORT_FUNC(PyArg_Parse)
|
||||||
EXPORT_FUNC(PyArg_ParseTuple)
|
EXPORT_FUNC(PyArg_ParseTuple)
|
||||||
EXPORT_FUNC(PyArg_ParseTupleAndKeywords)
|
EXPORT_FUNC(PyArg_ParseTupleAndKeywords)
|
||||||
|
@ -443,7 +443,7 @@ EXPORT_FUNC(PyObject_GenericGetAttr)
|
||||||
EXPORT_FUNC(PyObject_GenericGetDict)
|
EXPORT_FUNC(PyObject_GenericGetDict)
|
||||||
EXPORT_FUNC(PyObject_GenericSetAttr)
|
EXPORT_FUNC(PyObject_GenericSetAttr)
|
||||||
EXPORT_FUNC(PyObject_GenericSetDict)
|
EXPORT_FUNC(PyObject_GenericSetDict)
|
||||||
EXPORT_FUNC(PyObject_GetAiter)
|
EXPORT_FUNC(PyObject_GetAIter)
|
||||||
EXPORT_FUNC(PyObject_GetAttr)
|
EXPORT_FUNC(PyObject_GetAttr)
|
||||||
EXPORT_FUNC(PyObject_GetAttrString)
|
EXPORT_FUNC(PyObject_GetAttrString)
|
||||||
EXPORT_FUNC(PyObject_GetItem)
|
EXPORT_FUNC(PyObject_GetItem)
|
||||||
|
|
|
@ -1610,7 +1610,7 @@ static PyObject *
|
||||||
builtin_aiter(PyObject *module, PyObject *async_iterable)
|
builtin_aiter(PyObject *module, PyObject *async_iterable)
|
||||||
/*[clinic end generated code: output=1bae108d86f7960e input=473993d0cacc7d23]*/
|
/*[clinic end generated code: output=1bae108d86f7960e input=473993d0cacc7d23]*/
|
||||||
{
|
{
|
||||||
return PyObject_GetAiter(async_iterable);
|
return PyObject_GetAIter(async_iterable);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *PyAnextAwaitable_New(PyObject *, PyObject *);
|
PyObject *PyAnextAwaitable_New(PyObject *, PyObject *);
|
||||||
|
|
Loading…
Reference in New Issue