gh-91323: Revert "Allow overriding a future compliance check in asyncio.Task (GH-32197)" (GH-95442)

This reverts commit d4bb38f82b.
This commit is contained in:
Łukasz Langa 2022-08-04 15:51:38 +02:00 committed by GitHub
parent d0d0154443
commit 0342c93a6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 10 additions and 122 deletions

View File

@ -63,12 +63,6 @@ For this purpose the following, *private* constructors are listed:
*context* argument is added.
.. method:: Task._check_future(future)
Return ``True`` if *future* is attached to the same loop as the task, ``False``
otherwise.
.. versionadded:: 3.11
Task lifetime support

View File

@ -252,10 +252,6 @@ class Task(futures._PyFuture): # Inherit Python Task implementation
self._num_cancels_requested -= 1
return self._num_cancels_requested
def _check_future(self, future):
"""Return False if task and future loops are not compatible."""
return futures._get_loop(future) is self._loop
def __step(self, exc=None):
if self.done():
raise exceptions.InvalidStateError(
@ -296,7 +292,7 @@ class Task(futures._PyFuture): # Inherit Python Task implementation
blocking = getattr(result, '_asyncio_future_blocking', None)
if blocking is not None:
# Yielded Future must come from Future.__iter__().
if not self._check_future(result):
if futures._get_loop(result) is not self._loop:
new_exc = RuntimeError(
f'Task {self!r} got Future '
f'{result!r} attached to a different loop')

View File

@ -2380,13 +2380,7 @@ def add_subclass_tests(cls):
return super().add_done_callback(*args, **kwargs)
class Task(CommonFuture, BaseTask):
def __init__(self, *args, **kwargs):
self._check_future_called = 0
super().__init__(*args, **kwargs)
def _check_future(self, future):
self._check_future_called += 1
return super()._check_future(future)
pass
class Future(CommonFuture, BaseFuture):
pass
@ -2412,8 +2406,6 @@ def add_subclass_tests(cls):
dict(fut.calls),
{'add_done_callback': 1})
self.assertEqual(1, task._check_future_called)
# Add patched Task & Future back to the test case
cls.Task = Task
cls.Future = Future

View File

@ -23,7 +23,6 @@ _Py_IDENTIFIER(call_soon);
_Py_IDENTIFIER(cancel);
_Py_IDENTIFIER(get_event_loop);
_Py_IDENTIFIER(throw);
_Py_IDENTIFIER(_check_future);
/* State of the _asyncio module */
@ -1810,8 +1809,6 @@ class _asyncio.Task "TaskObj *" "&Task_Type"
static int task_call_step_soon(TaskObj *, PyObject *);
static PyObject * task_wakeup(TaskObj *, PyObject *);
static PyObject * task_step(TaskObj *, PyObject *);
static int task_check_future(TaskObj *, PyObject *);
static int task_check_future_exact(TaskObj *, PyObject *);
/* ----- Task._step wrapper */
@ -2286,6 +2283,7 @@ Returns the remaining number of cancellation requests.
static PyObject *
_asyncio_Task_uncancel_impl(TaskObj *self)
/*[clinic end generated code: output=58184d236a817d3c input=68f81a4b90b46be2]*/
/*[clinic end generated code]*/
{
if (self->task_num_cancels_requested > 0) {
self->task_num_cancels_requested -= 1;
@ -2293,21 +2291,6 @@ _asyncio_Task_uncancel_impl(TaskObj *self)
return PyLong_FromLong(self->task_num_cancels_requested);
}
/*[clinic input]
_asyncio.Task._check_future -> bool
future: object
Return False if task and future loops are not compatible.
[clinic start generated code]*/
static int
_asyncio_Task__check_future_impl(TaskObj *self, PyObject *future)
/*[clinic end generated code: output=a3bfba79295c8d57 input=3b1d6dfd6fe90aa5]*/
{
return task_check_future_exact(self, future);
}
/*[clinic input]
_asyncio.Task.get_stack
@ -2533,7 +2516,6 @@ static PyMethodDef TaskType_methods[] = {
_ASYNCIO_TASK_CANCEL_METHODDEF
_ASYNCIO_TASK_CANCELLING_METHODDEF
_ASYNCIO_TASK_UNCANCEL_METHODDEF
_ASYNCIO_TASK__CHECK_FUTURE_METHODDEF
_ASYNCIO_TASK_GET_STACK_METHODDEF
_ASYNCIO_TASK_PRINT_STACK_METHODDEF
_ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF
@ -2601,43 +2583,6 @@ TaskObj_dealloc(PyObject *self)
Py_TYPE(task)->tp_free(task);
}
static int
task_check_future_exact(TaskObj *task, PyObject *future)
{
int res;
if (Future_CheckExact(future) || Task_CheckExact(future)) {
FutureObj *fut = (FutureObj *)future;
res = (fut->fut_loop == task->task_loop);
} else {
PyObject *oloop = get_future_loop(future);
if (oloop == NULL) {
return -1;
}
res = (oloop == task->task_loop);
Py_DECREF(oloop);
}
return res;
}
static int
task_check_future(TaskObj *task, PyObject *future)
{
if (Task_CheckExact(task)) {
return task_check_future_exact(task, future);
} else {
PyObject * ret = _PyObject_CallMethodIdOneArg((PyObject *)task,
&PyId__check_future,
future);
if (ret == NULL) {
return -1;
}
int is_true = PyObject_IsTrue(ret);
Py_DECREF(ret);
return is_true;
}
}
static int
task_call_step_soon(TaskObj *task, PyObject *arg)
{
@ -2855,11 +2800,7 @@ task_step_impl(TaskObj *task, PyObject *exc)
FutureObj *fut = (FutureObj*)result;
/* Check if `result` future is attached to a different loop */
res = task_check_future(task, result);
if (res == -1) {
goto fail;
}
if (res == 0) {
if (fut->fut_loop != task->task_loop) {
goto different_loop;
}
@ -2931,13 +2872,15 @@ task_step_impl(TaskObj *task, PyObject *exc)
}
/* Check if `result` future is attached to a different loop */
res = task_check_future(task, result);
if (res == -1) {
PyObject *oloop = get_future_loop(result);
if (oloop == NULL) {
goto fail;
}
if (res == 0) {
if (oloop != task->task_loop) {
Py_DECREF(oloop);
goto different_loop;
}
Py_DECREF(oloop);
if (!blocking) {
goto yield_insteadof_yf;

View File

@ -466,43 +466,6 @@ _asyncio_Task_uncancel(TaskObj *self, PyObject *Py_UNUSED(ignored))
return _asyncio_Task_uncancel_impl(self);
}
PyDoc_STRVAR(_asyncio_Task__check_future__doc__,
"_check_future($self, /, future)\n"
"--\n"
"\n"
"Return False if task and future loops are not compatible.");
#define _ASYNCIO_TASK__CHECK_FUTURE_METHODDEF \
{"_check_future", _PyCFunction_CAST(_asyncio_Task__check_future), METH_FASTCALL|METH_KEYWORDS, _asyncio_Task__check_future__doc__},
static int
_asyncio_Task__check_future_impl(TaskObj *self, PyObject *future);
static PyObject *
_asyncio_Task__check_future(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"future", NULL};
static _PyArg_Parser _parser = {NULL, _keywords, "_check_future", 0};
PyObject *argsbuf[1];
PyObject *future;
int _return_value;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
goto exit;
}
future = args[0];
_return_value = _asyncio_Task__check_future_impl(self, future);
if ((_return_value == -1) && PyErr_Occurred()) {
goto exit;
}
return_value = PyBool_FromLong((long)_return_value);
exit:
return return_value;
}
PyDoc_STRVAR(_asyncio_Task_get_stack__doc__,
"get_stack($self, /, *, limit=None)\n"
"--\n"
@ -927,4 +890,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs,
exit:
return return_value;
}
/*[clinic end generated code: output=eccf150c9c30efd5 input=a9049054013a1b77]*/
/*[clinic end generated code: output=b4e678c915567934 input=a9049054013a1b77]*/