diff options
author | Vladimir Matveev <vladima@fb.com> | 2020-11-10 20:09:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-10 20:09:55 (GMT) |
commit | 1e996c3a3b51e9c6f1f4cea8a6dbcf3bcb865060 (patch) | |
tree | 3f3ffd5d90532c6f4b1ec013919e3677d63dd21c /Objects | |
parent | e59b2deffde61e5641cabd65034fa11b4db898ba (diff) | |
download | cpython-1e996c3a3b51e9c6f1f4cea8a6dbcf3bcb865060.zip cpython-1e996c3a3b51e9c6f1f4cea8a6dbcf3bcb865060.tar.gz cpython-1e996c3a3b51e9c6f1f4cea8a6dbcf3bcb865060.tar.bz2 |
bpo-42085: Introduce dedicated entry in PyAsyncMethods for sending values (#22780)
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 26 | ||||
-rw-r--r-- | Objects/genobject.c | 57 | ||||
-rw-r--r-- | Objects/typeobject.c | 7 | ||||
-rw-r--r-- | Objects/typeslots.inc | 1 |
4 files changed, 60 insertions, 31 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 5625498..44ed5b3 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2669,6 +2669,32 @@ PyIter_Next(PyObject *iter) return result; } +PySendResult +PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) +{ + _Py_IDENTIFIER(send); + assert(arg != NULL); + assert(result != NULL); + if (PyType_HasFeature(Py_TYPE(iter), Py_TPFLAGS_HAVE_AM_SEND)) { + assert (Py_TYPE(iter)->tp_as_async != NULL); + assert (Py_TYPE(iter)->tp_as_async->am_send != NULL); + return Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result); + } + if (arg == Py_None && PyIter_Check(iter)) { + *result = Py_TYPE(iter)->tp_iternext(iter); + } + else { + *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); + } + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + return PYGEN_ERROR; +} + /* * Flatten a sequence of bytes() objects into a C array of * NULL terminated string pointers with a NULL char* terminating the array. diff --git a/Objects/genobject.c b/Objects/genobject.c index c1b26e9..bde92b4 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -268,30 +268,10 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, return result ? PYGEN_RETURN : PYGEN_ERROR; } -PySendResult -PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) +static PySendResult +PyGen_am_send(PyGenObject *gen, PyObject *arg, PyObject **result) { - _Py_IDENTIFIER(send); - assert(arg != NULL); - assert(result != NULL); - - if (PyGen_CheckExact(iter) || PyCoro_CheckExact(iter)) { - return gen_send_ex2((PyGenObject *)iter, arg, result, 0, 0); - } - - if (arg == Py_None && PyIter_Check(iter)) { - *result = Py_TYPE(iter)->tp_iternext(iter); - } - else { - *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); - } - if (*result != NULL) { - return PYGEN_NEXT; - } - if (_PyGen_FetchStopIterationValue(result) == 0) { - return PYGEN_RETURN; - } - return PYGEN_ERROR; + return gen_send_ex2(gen, arg, result, 0, 0); } static PyObject * @@ -788,6 +768,14 @@ static PyMethodDef gen_methods[] = { {NULL, NULL} /* Sentinel */ }; +static PyAsyncMethods gen_as_async = { + 0, /* am_await */ + 0, /* am_aiter */ + 0, /* am_anext */ + (sendfunc)PyGen_am_send, /* am_send */ +}; + + PyTypeObject PyGen_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "generator", /* tp_name */ @@ -798,7 +786,7 @@ PyTypeObject PyGen_Type = { 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_as_async */ + &gen_as_async, /* tp_as_async */ (reprfunc)gen_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -809,7 +797,8 @@ PyTypeObject PyGen_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_HAVE_AM_SEND, /* tp_flags */ 0, /* tp_doc */ (traverseproc)gen_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -1031,7 +1020,8 @@ static PyMethodDef coro_methods[] = { static PyAsyncMethods coro_as_async = { (unaryfunc)coro_await, /* am_await */ 0, /* am_aiter */ - 0 /* am_anext */ + 0, /* am_anext */ + (sendfunc)PyGen_am_send, /* am_send */ }; PyTypeObject PyCoro_Type = { @@ -1055,7 +1045,8 @@ PyTypeObject PyCoro_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_HAVE_AM_SEND, /* tp_flags */ 0, /* tp_doc */ (traverseproc)gen_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -1413,7 +1404,8 @@ static PyMethodDef async_gen_methods[] = { static PyAsyncMethods async_gen_as_async = { 0, /* am_await */ PyObject_SelfIter, /* am_aiter */ - (unaryfunc)async_gen_anext /* am_anext */ + (unaryfunc)async_gen_anext, /* am_anext */ + (sendfunc)PyGen_am_send, /* am_send */ }; @@ -1438,7 +1430,8 @@ PyTypeObject PyAsyncGen_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_HAVE_AM_SEND, /* tp_flags */ 0, /* tp_doc */ (traverseproc)async_gen_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -1676,7 +1669,8 @@ static PyMethodDef async_gen_asend_methods[] = { static PyAsyncMethods async_gen_asend_as_async = { PyObject_SelfIter, /* am_await */ 0, /* am_aiter */ - 0 /* am_anext */ + 0, /* am_anext */ + 0, /* am_send */ }; @@ -2084,7 +2078,8 @@ static PyMethodDef async_gen_athrow_methods[] = { static PyAsyncMethods async_gen_athrow_as_async = { PyObject_SelfIter, /* am_await */ 0, /* am_aiter */ - 0 /* am_anext */ + 0, /* am_anext */ + 0, /* am_send */ }; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 55bf9b3..b4188b8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5427,6 +5427,13 @@ PyType_Ready(PyTypeObject *type) _PyObject_ASSERT((PyObject *)type, type->tp_vectorcall_offset > 0); _PyObject_ASSERT((PyObject *)type, type->tp_call != NULL); } + /* Consistency check for Py_TPFLAGS_HAVE_AM_SEND - flag requires + * type->tp_as_async->am_send to be present. + */ + if (type->tp_flags & Py_TPFLAGS_HAVE_AM_SEND) { + _PyObject_ASSERT((PyObject *)type, type->tp_as_async != NULL); + _PyObject_ASSERT((PyObject *)type, type->tp_as_async->am_send != NULL); + } type->tp_flags |= Py_TPFLAGS_READYING; diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc index ffc9bb2..cc4ef11 100644 --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -79,3 +79,4 @@ offsetof(PyHeapTypeObject, as_async.am_await), offsetof(PyHeapTypeObject, as_async.am_aiter), offsetof(PyHeapTypeObject, as_async.am_anext), offsetof(PyHeapTypeObject, ht_type.tp_finalize), +offsetof(PyHeapTypeObject, as_async.am_send), |