bpo-31185: Fixed miscellaneous errors in asyncio speedup module. (#3076)

This commit is contained in:
Serhiy Storchaka 2017-09-03 08:10:14 +03:00 committed by GitHub
parent 8df44ee8e0
commit bca4939d80
4 changed files with 250 additions and 221 deletions

View File

@ -100,8 +100,8 @@ class DuckTests(test_utils.TestCase):
class BaseFutureTests: class BaseFutureTests:
def _new_future(self, loop=None): def _new_future(self, *args, **kwargs):
raise NotImplementedError return self.cls(*args, **kwargs)
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -147,6 +147,39 @@ class BaseFutureTests:
# Make sure Future doesn't accept a positional argument # Make sure Future doesn't accept a positional argument
self.assertRaises(TypeError, self._new_future, 42) self.assertRaises(TypeError, self._new_future, 42)
def test_uninitialized(self):
fut = self.cls.__new__(self.cls, loop=self.loop)
self.assertRaises(asyncio.InvalidStateError, fut.result)
fut = self.cls.__new__(self.cls, loop=self.loop)
self.assertRaises(asyncio.InvalidStateError, fut.exception)
fut = self.cls.__new__(self.cls, loop=self.loop)
with self.assertRaises((RuntimeError, AttributeError)):
fut.set_result(None)
fut = self.cls.__new__(self.cls, loop=self.loop)
with self.assertRaises((RuntimeError, AttributeError)):
fut.set_exception(Exception)
fut = self.cls.__new__(self.cls, loop=self.loop)
with self.assertRaises((RuntimeError, AttributeError)):
fut.cancel()
fut = self.cls.__new__(self.cls, loop=self.loop)
with self.assertRaises((RuntimeError, AttributeError)):
fut.add_done_callback(lambda f: None)
fut = self.cls.__new__(self.cls, loop=self.loop)
with self.assertRaises((RuntimeError, AttributeError)):
fut.remove_done_callback(lambda f: None)
fut = self.cls.__new__(self.cls, loop=self.loop)
with self.assertRaises((RuntimeError, AttributeError)):
fut._schedule_callbacks()
fut = self.cls.__new__(self.cls, loop=self.loop)
try:
repr(fut)
except AttributeError:
pass
fut = self.cls.__new__(self.cls, loop=self.loop)
fut.cancelled()
fut.done()
iter(fut)
def test_cancel(self): def test_cancel(self):
f = self._new_future(loop=self.loop) f = self._new_future(loop=self.loop)
self.assertTrue(f.cancel()) self.assertTrue(f.cancel())
@ -501,15 +534,11 @@ class BaseFutureTests:
@unittest.skipUnless(hasattr(futures, '_CFuture'), @unittest.skipUnless(hasattr(futures, '_CFuture'),
'requires the C _asyncio module') 'requires the C _asyncio module')
class CFutureTests(BaseFutureTests, test_utils.TestCase): class CFutureTests(BaseFutureTests, test_utils.TestCase):
cls = getattr(futures, '_CFuture')
def _new_future(self, *args, **kwargs):
return futures._CFuture(*args, **kwargs)
class PyFutureTests(BaseFutureTests, test_utils.TestCase): class PyFutureTests(BaseFutureTests, test_utils.TestCase):
cls = futures._PyFuture
def _new_future(self, *args, **kwargs):
return futures._PyFuture(*args, **kwargs)
class BaseFutureDoneCallbackTests(): class BaseFutureDoneCallbackTests():

View File

@ -0,0 +1 @@
Fixed miscellaneous errors in asyncio speedup module.

View File

@ -68,7 +68,7 @@ typedef struct {
PyObject_HEAD PyObject_HEAD
TaskObj *sw_task; TaskObj *sw_task;
PyObject *sw_arg; PyObject *sw_arg;
} TaskSendMethWrapper; } TaskStepMethWrapper;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
@ -92,11 +92,11 @@ static int
future_schedule_callbacks(FutureObj *fut) future_schedule_callbacks(FutureObj *fut)
{ {
Py_ssize_t len; Py_ssize_t len;
PyObject* iters; PyObject *callbacks;
int i; int i;
if (fut->fut_callbacks == NULL) { if (fut->fut_callbacks == NULL) {
PyErr_SetString(PyExc_RuntimeError, "NULL callbacks"); PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object");
return -1; return -1;
} }
@ -105,42 +105,41 @@ future_schedule_callbacks(FutureObj *fut)
return 0; return 0;
} }
iters = PyList_GetSlice(fut->fut_callbacks, 0, len); callbacks = PyList_GetSlice(fut->fut_callbacks, 0, len);
if (iters == NULL) { if (callbacks == NULL) {
return -1; return -1;
} }
if (PyList_SetSlice(fut->fut_callbacks, 0, len, NULL) < 0) { if (PyList_SetSlice(fut->fut_callbacks, 0, len, NULL) < 0) {
Py_DECREF(iters); Py_DECREF(callbacks);
return -1; return -1;
} }
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
PyObject *handle = NULL; PyObject *handle;
PyObject *cb = PyList_GET_ITEM(iters, i); PyObject *cb = PyList_GET_ITEM(callbacks, i);
handle = _PyObject_CallMethodIdObjArgs(fut->fut_loop, &PyId_call_soon, handle = _PyObject_CallMethodIdObjArgs(fut->fut_loop, &PyId_call_soon,
cb, fut, NULL); cb, fut, NULL);
if (handle == NULL) { if (handle == NULL) {
Py_DECREF(iters); Py_DECREF(callbacks);
return -1; return -1;
} }
else { Py_DECREF(handle);
Py_DECREF(handle);
}
} }
Py_DECREF(iters); Py_DECREF(callbacks);
return 0; return 0;
} }
static int static int
future_init(FutureObj *fut, PyObject *loop) future_init(FutureObj *fut, PyObject *loop)
{ {
PyObject *res = NULL; PyObject *res;
int is_true;
_Py_IDENTIFIER(get_debug); _Py_IDENTIFIER(get_debug);
if (loop == NULL || loop == Py_None) { if (loop == Py_None) {
loop = _PyObject_CallNoArg(asyncio_get_event_loop); loop = _PyObject_CallNoArg(asyncio_get_event_loop);
if (loop == NULL) { if (loop == NULL) {
return -1; return -1;
@ -149,25 +148,25 @@ future_init(FutureObj *fut, PyObject *loop)
else { else {
Py_INCREF(loop); Py_INCREF(loop);
} }
Py_CLEAR(fut->fut_loop); Py_XSETREF(fut->fut_loop, loop);
fut->fut_loop = loop;
res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL); res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL);
if (res == NULL) { if (res == NULL) {
return -1; return -1;
} }
if (PyObject_IsTrue(res)) { is_true = PyObject_IsTrue(res);
Py_CLEAR(res); Py_DECREF(res);
fut->fut_source_tb = _PyObject_CallNoArg(traceback_extract_stack); if (is_true < 0) {
return -1;
}
if (is_true) {
Py_XSETREF(fut->fut_source_tb, _PyObject_CallNoArg(traceback_extract_stack));
if (fut->fut_source_tb == NULL) { if (fut->fut_source_tb == NULL) {
return -1; return -1;
} }
} }
else {
Py_CLEAR(res);
}
fut->fut_callbacks = PyList_New(0); Py_XSETREF(fut->fut_callbacks, PyList_New(0));
if (fut->fut_callbacks == NULL) { if (fut->fut_callbacks == NULL) {
return -1; return -1;
} }
@ -183,6 +182,7 @@ future_set_result(FutureObj *fut, PyObject *res)
return NULL; return NULL;
} }
assert(!fut->fut_result);
Py_INCREF(res); Py_INCREF(res);
fut->fut_result = res; fut->fut_result = res;
fut->fut_state = STATE_FINISHED; fut->fut_state = STATE_FINISHED;
@ -208,6 +208,11 @@ future_set_exception(FutureObj *fut, PyObject *exc)
if (exc_val == NULL) { if (exc_val == NULL) {
return NULL; return NULL;
} }
if (fut->fut_state != STATE_PENDING) {
Py_DECREF(exc_val);
PyErr_SetString(asyncio_InvalidStateError, "invalid state");
return NULL;
}
} }
else { else {
exc_val = exc; exc_val = exc;
@ -226,6 +231,7 @@ future_set_exception(FutureObj *fut, PyObject *exc)
return NULL; return NULL;
} }
assert(!fut->fut_exception);
fut->fut_exception = exc_val; fut->fut_exception = exc_val;
fut->fut_state = STATE_FINISHED; fut->fut_state = STATE_FINISHED;
@ -240,31 +246,14 @@ future_set_exception(FutureObj *fut, PyObject *exc)
static int static int
future_get_result(FutureObj *fut, PyObject **result) future_get_result(FutureObj *fut, PyObject **result)
{ {
PyObject *exc;
if (fut->fut_state == STATE_CANCELLED) { if (fut->fut_state == STATE_CANCELLED) {
exc = _PyObject_CallNoArg(asyncio_CancelledError); PyErr_SetNone(asyncio_CancelledError);
if (exc == NULL) { return -1;
return -1;
}
*result = exc;
return 1;
} }
if (fut->fut_state != STATE_FINISHED) { if (fut->fut_state != STATE_FINISHED) {
PyObject *msg = PyUnicode_FromString("Result is not ready."); PyErr_SetString(asyncio_InvalidStateError, "Result is not set.");
if (msg == NULL) { return -1;
return -1;
}
exc = PyObject_CallFunctionObjArgs(asyncio_InvalidStateError, msg, NULL);
Py_DECREF(msg);
if (exc == NULL) {
return -1;
}
*result = exc;
return 1;
} }
fut->fut_log_tb = 0; fut->fut_log_tb = 0;
@ -286,15 +275,16 @@ future_add_done_callback(FutureObj *fut, PyObject *arg)
PyObject *handle = _PyObject_CallMethodIdObjArgs(fut->fut_loop, PyObject *handle = _PyObject_CallMethodIdObjArgs(fut->fut_loop,
&PyId_call_soon, &PyId_call_soon,
arg, fut, NULL); arg, fut, NULL);
if (handle == NULL) { if (handle == NULL) {
return NULL; return NULL;
} }
else { Py_DECREF(handle);
Py_DECREF(handle);
}
} }
else { else {
if (fut->fut_callbacks == NULL) {
PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object");
return NULL;
}
int err = PyList_Append(fut->fut_callbacks, arg); int err = PyList_Append(fut->fut_callbacks, arg);
if (err != 0) { if (err != 0) {
return NULL; return NULL;
@ -324,7 +314,7 @@ future_cancel(FutureObj *fut)
_asyncio.Future.__init__ _asyncio.Future.__init__
* *
loop: 'O' = NULL loop: object = None
This class is *almost* compatible with concurrent.futures.Future. This class is *almost* compatible with concurrent.futures.Future.
@ -342,7 +332,7 @@ This class is *almost* compatible with concurrent.futures.Future.
static int static int
_asyncio_Future___init___impl(FutureObj *self, PyObject *loop) _asyncio_Future___init___impl(FutureObj *self, PyObject *loop)
/*[clinic end generated code: output=9ed75799eaccb5d6 input=8e1681f23605be2d]*/ /*[clinic end generated code: output=9ed75799eaccb5d6 input=89af317082bc0bf8]*/
{ {
return future_init(self, loop); return future_init(self, loop);
@ -420,12 +410,12 @@ _asyncio_Future_exception_impl(FutureObj *self)
/*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/ /*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/
{ {
if (self->fut_state == STATE_CANCELLED) { if (self->fut_state == STATE_CANCELLED) {
PyErr_SetString(asyncio_CancelledError, ""); PyErr_SetNone(asyncio_CancelledError);
return NULL; return NULL;
} }
if (self->fut_state != STATE_FINISHED) { if (self->fut_state != STATE_FINISHED) {
PyErr_SetString(asyncio_InvalidStateError, "Result is not ready."); PyErr_SetString(asyncio_InvalidStateError, "Exception is not set.");
return NULL; return NULL;
} }
@ -441,7 +431,7 @@ _asyncio_Future_exception_impl(FutureObj *self)
/*[clinic input] /*[clinic input]
_asyncio.Future.set_result _asyncio.Future.set_result
res: 'O' res: object
/ /
Mark the future done and set its result. Mark the future done and set its result.
@ -452,7 +442,7 @@ InvalidStateError.
static PyObject * static PyObject *
_asyncio_Future_set_result(FutureObj *self, PyObject *res) _asyncio_Future_set_result(FutureObj *self, PyObject *res)
/*[clinic end generated code: output=a620abfc2796bfb6 input=8619565e0503357e]*/ /*[clinic end generated code: output=a620abfc2796bfb6 input=5b9dc180f1baa56d]*/
{ {
return future_set_result(self, res); return future_set_result(self, res);
} }
@ -460,7 +450,7 @@ _asyncio_Future_set_result(FutureObj *self, PyObject *res)
/*[clinic input] /*[clinic input]
_asyncio.Future.set_exception _asyncio.Future.set_exception
exception: 'O' exception: object
/ /
Mark the future done and set an exception. Mark the future done and set an exception.
@ -471,7 +461,7 @@ InvalidStateError.
static PyObject * static PyObject *
_asyncio_Future_set_exception(FutureObj *self, PyObject *exception) _asyncio_Future_set_exception(FutureObj *self, PyObject *exception)
/*[clinic end generated code: output=f1c1b0cd321be360 input=1377dbe15e6ea186]*/ /*[clinic end generated code: output=f1c1b0cd321be360 input=e45b7d7aa71cc66d]*/
{ {
return future_set_exception(self, exception); return future_set_exception(self, exception);
} }
@ -479,7 +469,7 @@ _asyncio_Future_set_exception(FutureObj *self, PyObject *exception)
/*[clinic input] /*[clinic input]
_asyncio.Future.add_done_callback _asyncio.Future.add_done_callback
fn: 'O' fn: object
/ /
Add a callback to be run when the future becomes done. Add a callback to be run when the future becomes done.
@ -491,7 +481,7 @@ scheduled with call_soon.
static PyObject * static PyObject *
_asyncio_Future_add_done_callback(FutureObj *self, PyObject *fn) _asyncio_Future_add_done_callback(FutureObj *self, PyObject *fn)
/*[clinic end generated code: output=819e09629b2ec2b5 input=8cce187e32cec6a8]*/ /*[clinic end generated code: output=819e09629b2ec2b5 input=8f818b39990b027d]*/
{ {
return future_add_done_callback(self, fn); return future_add_done_callback(self, fn);
} }
@ -499,7 +489,7 @@ _asyncio_Future_add_done_callback(FutureObj *self, PyObject *fn)
/*[clinic input] /*[clinic input]
_asyncio.Future.remove_done_callback _asyncio.Future.remove_done_callback
fn: 'O' fn: object
/ /
Remove all instances of a callback from the "call when done" list. Remove all instances of a callback from the "call when done" list.
@ -509,11 +499,16 @@ Returns the number of callbacks removed.
static PyObject * static PyObject *
_asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn)
/*[clinic end generated code: output=5ab1fb52b24ef31f input=3fedb73e1409c31c]*/ /*[clinic end generated code: output=5ab1fb52b24ef31f input=0a43280a149d505b]*/
{ {
PyObject *newlist; PyObject *newlist;
Py_ssize_t len, i, j=0; Py_ssize_t len, i, j=0;
if (self->fut_callbacks == NULL) {
PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object");
return NULL;
}
len = PyList_GET_SIZE(self->fut_callbacks); len = PyList_GET_SIZE(self->fut_callbacks);
if (len == 0) { if (len == 0) {
return PyLong_FromSsize_t(0); return PyLong_FromSsize_t(0);
@ -527,29 +522,31 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn)
for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) { for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) {
int ret; int ret;
PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i); PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i);
Py_INCREF(item);
if ((ret = PyObject_RichCompareBool(fn, item, Py_EQ)) < 0) { ret = PyObject_RichCompareBool(fn, item, Py_EQ);
goto fail;
}
if (ret == 0) { if (ret == 0) {
if (j < len) { if (j < len) {
Py_INCREF(item);
PyList_SET_ITEM(newlist, j, item); PyList_SET_ITEM(newlist, j, item);
j++; j++;
continue;
} }
else { ret = PyList_Append(newlist, item);
if (PyList_Append(newlist, item)) { }
goto fail; Py_DECREF(item);
} if (ret < 0) {
} goto fail;
} }
} }
if (PyList_SetSlice(newlist, j, len, NULL) < 0) { if (j < len) {
goto fail; Py_SIZE(newlist) = j;
} }
if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) { j = PyList_GET_SIZE(newlist);
goto fail; len = PyList_GET_SIZE(self->fut_callbacks);
if (j != len) {
if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) {
goto fail;
}
} }
Py_DECREF(newlist); Py_DECREF(newlist);
return PyLong_FromSsize_t(len - j); return PyLong_FromSsize_t(len - j);
@ -730,7 +727,7 @@ FutureObj_get_state(FutureObj *fut)
default: default:
assert (0); assert (0);
} }
Py_INCREF(ret); Py_XINCREF(ret);
return ret; return ret;
} }
@ -766,25 +763,14 @@ FutureObj_repr(FutureObj *fut)
{ {
_Py_IDENTIFIER(_repr_info); _Py_IDENTIFIER(_repr_info);
PyObject *_repr_info = _PyUnicode_FromId(&PyId__repr_info); // borrowed PyObject *rinfo = _PyObject_CallMethodIdObjArgs((PyObject*)fut,
if (_repr_info == NULL) { &PyId__repr_info,
return NULL; NULL);
}
PyObject *rinfo = PyObject_CallMethodObjArgs((PyObject*)fut, _repr_info,
NULL);
if (rinfo == NULL) { if (rinfo == NULL) {
return NULL; return NULL;
} }
PyObject *sp = PyUnicode_FromString(" "); PyObject *rinfo_s = PyUnicode_Join(NULL, rinfo);
if (sp == NULL) {
Py_DECREF(rinfo);
return NULL;
}
PyObject *rinfo_s = PyUnicode_Join(sp, rinfo);
Py_DECREF(sp);
Py_DECREF(rinfo); Py_DECREF(rinfo);
if (rinfo_s == NULL) { if (rinfo_s == NULL) {
return NULL; return NULL;
@ -794,7 +780,7 @@ FutureObj_repr(FutureObj *fut)
PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut),
"__name__"); "__name__");
if (type_name != NULL) { if (type_name != NULL) {
rstr = PyUnicode_FromFormat("<%S %S>", type_name, rinfo_s); rstr = PyUnicode_FromFormat("<%S %U>", type_name, rinfo_s);
Py_DECREF(type_name); Py_DECREF(type_name);
} }
Py_DECREF(rinfo_s); Py_DECREF(rinfo_s);
@ -810,22 +796,21 @@ FutureObj_finalize(FutureObj *fut)
_Py_IDENTIFIER(future); _Py_IDENTIFIER(future);
_Py_IDENTIFIER(source_traceback); _Py_IDENTIFIER(source_traceback);
PyObject *error_type, *error_value, *error_traceback;
PyObject *context;
PyObject *type_name;
PyObject *message = NULL;
PyObject *func;
if (!fut->fut_log_tb) { if (!fut->fut_log_tb) {
return; return;
} }
assert(fut->fut_exception != NULL); assert(fut->fut_exception != NULL);
fut->fut_log_tb = 0;; fut->fut_log_tb = 0;
PyObject *error_type, *error_value, *error_traceback;
/* Save the current exception, if any. */ /* Save the current exception, if any. */
PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyObject *context = NULL;
PyObject *type_name = NULL;
PyObject *message = NULL;
PyObject *func = NULL;
PyObject *res = NULL;
context = PyDict_New(); context = PyDict_New();
if (context == NULL) { if (context == NULL) {
goto finally; goto finally;
@ -838,6 +823,7 @@ FutureObj_finalize(FutureObj *fut)
message = PyUnicode_FromFormat( message = PyUnicode_FromFormat(
"%S exception was never retrieved", type_name); "%S exception was never retrieved", type_name);
Py_DECREF(type_name);
if (message == NULL) { if (message == NULL) {
goto finally; goto finally;
} }
@ -856,18 +842,19 @@ FutureObj_finalize(FutureObj *fut)
func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler); func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler);
if (func != NULL) { if (func != NULL) {
res = PyObject_CallFunctionObjArgs(func, context, NULL); PyObject *res = PyObject_CallFunctionObjArgs(func, context, NULL);
if (res == NULL) { if (res == NULL) {
PyErr_WriteUnraisable(func); PyErr_WriteUnraisable(func);
} }
else {
Py_DECREF(res);
}
Py_DECREF(func);
} }
finally: finally:
Py_CLEAR(context); Py_XDECREF(context);
Py_CLEAR(type_name); Py_XDECREF(message);
Py_CLEAR(message);
Py_CLEAR(func);
Py_CLEAR(res);
/* Restore the saved exception. */ /* Restore the saved exception. */
PyErr_Restore(error_type, error_value, error_traceback); PyErr_Restore(error_type, error_value, error_traceback);
@ -1014,22 +1001,19 @@ FutureIter_iternext(futureiterobject *it)
Py_INCREF(fut); Py_INCREF(fut);
return (PyObject *)fut; return (PyObject *)fut;
} }
PyErr_Format(PyExc_AssertionError, PyErr_SetString(PyExc_AssertionError,
"yield from wasn't used with future"); "yield from wasn't used with future");
return NULL; return NULL;
} }
it->future = NULL;
res = _asyncio_Future_result_impl(fut); res = _asyncio_Future_result_impl(fut);
if (res != NULL) { if (res != NULL) {
/* The result of the Future is not an exception. */ /* The result of the Future is not an exception. */
if (_PyGen_SetStopIterationValue(res) < 0) { (void)_PyGen_SetStopIterationValue(res);
Py_DECREF(res);
return NULL;
}
Py_DECREF(res); Py_DECREF(res);
} }
it->future = NULL;
Py_DECREF(fut); Py_DECREF(fut);
return NULL; return NULL;
} }
@ -1046,7 +1030,7 @@ FutureIter_send(futureiterobject *self, PyObject *unused)
static PyObject * static PyObject *
FutureIter_throw(futureiterobject *self, PyObject *args) FutureIter_throw(futureiterobject *self, PyObject *args)
{ {
PyObject *type=NULL, *val=NULL, *tb=NULL; PyObject *type, *val = NULL, *tb = NULL;
if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb)) if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb))
return NULL; return NULL;
@ -1090,7 +1074,7 @@ FutureIter_throw(futureiterobject *self, PyObject *args)
PyErr_Restore(type, val, tb); PyErr_Restore(type, val, tb);
return FutureIter_iternext(self); return NULL;
fail: fail:
Py_DECREF(type); Py_DECREF(type);
@ -1171,7 +1155,7 @@ static PyObject * task_step(TaskObj *, PyObject *);
/* ----- Task._step wrapper */ /* ----- Task._step wrapper */
static int static int
TaskSendMethWrapper_clear(TaskSendMethWrapper *o) TaskStepMethWrapper_clear(TaskStepMethWrapper *o)
{ {
Py_CLEAR(o->sw_task); Py_CLEAR(o->sw_task);
Py_CLEAR(o->sw_arg); Py_CLEAR(o->sw_arg);
@ -1179,22 +1163,30 @@ TaskSendMethWrapper_clear(TaskSendMethWrapper *o)
} }
static void static void
TaskSendMethWrapper_dealloc(TaskSendMethWrapper *o) TaskStepMethWrapper_dealloc(TaskStepMethWrapper *o)
{ {
PyObject_GC_UnTrack(o); PyObject_GC_UnTrack(o);
(void)TaskSendMethWrapper_clear(o); (void)TaskStepMethWrapper_clear(o);
Py_TYPE(o)->tp_free(o); Py_TYPE(o)->tp_free(o);
} }
static PyObject * static PyObject *
TaskSendMethWrapper_call(TaskSendMethWrapper *o, TaskStepMethWrapper_call(TaskStepMethWrapper *o,
PyObject *args, PyObject *kwds) PyObject *args, PyObject *kwds)
{ {
if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) {
PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments");
return NULL;
}
if (args != NULL && PyTuple_GET_SIZE(args) != 0) {
PyErr_SetString(PyExc_TypeError, "function takes no positional arguments");
return NULL;
}
return task_call_step(o->sw_task, o->sw_arg); return task_call_step(o->sw_task, o->sw_arg);
} }
static int static int
TaskSendMethWrapper_traverse(TaskSendMethWrapper *o, TaskStepMethWrapper_traverse(TaskStepMethWrapper *o,
visitproc visit, void *arg) visitproc visit, void *arg)
{ {
Py_VISIT(o->sw_task); Py_VISIT(o->sw_task);
@ -1203,7 +1195,7 @@ TaskSendMethWrapper_traverse(TaskSendMethWrapper *o,
} }
static PyObject * static PyObject *
TaskSendMethWrapper_get___self__(TaskSendMethWrapper *o) TaskStepMethWrapper_get___self__(TaskStepMethWrapper *o)
{ {
if (o->sw_task) { if (o->sw_task) {
Py_INCREF(o->sw_task); Py_INCREF(o->sw_task);
@ -1212,30 +1204,30 @@ TaskSendMethWrapper_get___self__(TaskSendMethWrapper *o)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static PyGetSetDef TaskSendMethWrapper_getsetlist[] = { static PyGetSetDef TaskStepMethWrapper_getsetlist[] = {
{"__self__", (getter)TaskSendMethWrapper_get___self__, NULL, NULL}, {"__self__", (getter)TaskStepMethWrapper_get___self__, NULL, NULL},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };
PyTypeObject TaskSendMethWrapper_Type = { PyTypeObject TaskStepMethWrapper_Type = {
PyVarObject_HEAD_INIT(NULL, 0) PyVarObject_HEAD_INIT(NULL, 0)
"TaskSendMethWrapper", "TaskStepMethWrapper",
.tp_basicsize = sizeof(TaskSendMethWrapper), .tp_basicsize = sizeof(TaskStepMethWrapper),
.tp_itemsize = 0, .tp_itemsize = 0,
.tp_getset = TaskSendMethWrapper_getsetlist, .tp_getset = TaskStepMethWrapper_getsetlist,
.tp_dealloc = (destructor)TaskSendMethWrapper_dealloc, .tp_dealloc = (destructor)TaskStepMethWrapper_dealloc,
.tp_call = (ternaryfunc)TaskSendMethWrapper_call, .tp_call = (ternaryfunc)TaskStepMethWrapper_call,
.tp_getattro = PyObject_GenericGetAttr, .tp_getattro = PyObject_GenericGetAttr,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
.tp_traverse = (traverseproc)TaskSendMethWrapper_traverse, .tp_traverse = (traverseproc)TaskStepMethWrapper_traverse,
.tp_clear = (inquiry)TaskSendMethWrapper_clear, .tp_clear = (inquiry)TaskStepMethWrapper_clear,
}; };
static PyObject * static PyObject *
TaskSendMethWrapper_new(TaskObj *task, PyObject *arg) TaskStepMethWrapper_new(TaskObj *task, PyObject *arg)
{ {
TaskSendMethWrapper *o; TaskStepMethWrapper *o;
o = PyObject_GC_New(TaskSendMethWrapper, &TaskSendMethWrapper_Type); o = PyObject_GC_New(TaskStepMethWrapper, &TaskStepMethWrapper_Type);
if (o == NULL) { if (o == NULL) {
return NULL; return NULL;
} }
@ -1258,7 +1250,11 @@ TaskWakeupMethWrapper_call(TaskWakeupMethWrapper *o,
{ {
PyObject *fut; PyObject *fut;
if (!PyArg_ParseTuple(args, "O|", &fut)) { if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) {
PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments");
return NULL;
}
if (!PyArg_ParseTuple(args, "O", &fut)) {
return NULL; return NULL;
} }
@ -1322,16 +1318,16 @@ TaskWakeupMethWrapper_new(TaskObj *task)
/*[clinic input] /*[clinic input]
_asyncio.Task.__init__ _asyncio.Task.__init__
coro: 'O' coro: object
* *
loop: 'O' = NULL loop: object = None
A coroutine wrapped in a Future. A coroutine wrapped in a Future.
[clinic start generated code]*/ [clinic start generated code]*/
static int static int
_asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop) _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)
/*[clinic end generated code: output=9f24774c2287fc2f input=71d8d28c201a18cd]*/ /*[clinic end generated code: output=9f24774c2287fc2f input=8d132974b049593e]*/
{ {
PyObject *res; PyObject *res;
_Py_IDENTIFIER(add); _Py_IDENTIFIER(add);
@ -1437,7 +1433,7 @@ TaskObj_get_fut_waiter(TaskObj *task)
@classmethod @classmethod
_asyncio.Task.current_task _asyncio.Task.current_task
loop: 'O' = None loop: object = None
Return the currently running task in an event loop or None. Return the currently running task in an event loop or None.
@ -1448,7 +1444,7 @@ None is returned when called not in the context of a Task.
static PyObject * static PyObject *
_asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop) _asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop)
/*[clinic end generated code: output=99fbe7332c516e03 input=a0d6cdf2e3b243e1]*/ /*[clinic end generated code: output=99fbe7332c516e03 input=cd14770c5b79c7eb]*/
{ {
PyObject *res; PyObject *res;
@ -1510,12 +1506,14 @@ task_all_tasks(PyObject *loop)
Py_DECREF(task_loop); Py_DECREF(task_loop);
Py_DECREF(task); Py_DECREF(task);
} }
if (PyErr_Occurred()) {
goto fail;
}
Py_DECREF(iter); Py_DECREF(iter);
return set; return set;
fail: fail:
Py_XDECREF(set); Py_DECREF(set);
Py_XDECREF(iter); Py_XDECREF(iter);
return NULL; return NULL;
} }
@ -1524,7 +1522,7 @@ fail:
@classmethod @classmethod
_asyncio.Task.all_tasks _asyncio.Task.all_tasks
loop: 'O' = None loop: object = None
Return a set of all tasks for an event loop. Return a set of all tasks for an event loop.
@ -1533,7 +1531,7 @@ By default all tasks for the current event loop are returned.
static PyObject * static PyObject *
_asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop) _asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop)
/*[clinic end generated code: output=11f9b20749ccca5d input=c6f5b53bd487488f]*/ /*[clinic end generated code: output=11f9b20749ccca5d input=497f80bc9ce726b5]*/
{ {
PyObject *res; PyObject *res;
@ -1627,7 +1625,7 @@ _asyncio_Task_cancel_impl(TaskObj *self)
_asyncio.Task.get_stack _asyncio.Task.get_stack
* *
limit: 'O' = None limit: object = None
Return the list of stack frames for this task's coroutine. Return the list of stack frames for this task's coroutine.
@ -1652,7 +1650,7 @@ returned for a suspended coroutine.
static PyObject * static PyObject *
_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit) _asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit)
/*[clinic end generated code: output=c9aeeeebd1e18118 input=b1920230a766d17a]*/ /*[clinic end generated code: output=c9aeeeebd1e18118 input=05b323d42b809b90]*/
{ {
return PyObject_CallFunctionObjArgs( return PyObject_CallFunctionObjArgs(
asyncio_task_get_stack_func, self, limit, NULL); asyncio_task_get_stack_func, self, limit, NULL);
@ -1662,8 +1660,8 @@ _asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit)
_asyncio.Task.print_stack _asyncio.Task.print_stack
* *
limit: 'O' = None limit: object = None
file: 'O' = None file: object = None
Print the stack or traceback for this task's coroutine. Print the stack or traceback for this task's coroutine.
@ -1677,7 +1675,7 @@ to sys.stderr.
static PyObject * static PyObject *
_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, _asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit,
PyObject *file) PyObject *file)
/*[clinic end generated code: output=7339e10314cd3f4d input=19f1e99ab5400bc3]*/ /*[clinic end generated code: output=7339e10314cd3f4d input=1a0352913b7fcd92]*/
{ {
return PyObject_CallFunctionObjArgs( return PyObject_CallFunctionObjArgs(
asyncio_task_print_stack_func, self, limit, file, NULL); asyncio_task_print_stack_func, self, limit, file, NULL);
@ -1686,12 +1684,12 @@ _asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit,
/*[clinic input] /*[clinic input]
_asyncio.Task._step _asyncio.Task._step
exc: 'O' = NULL exc: object = None
[clinic start generated code]*/ [clinic start generated code]*/
static PyObject * static PyObject *
_asyncio_Task__step_impl(TaskObj *self, PyObject *exc) _asyncio_Task__step_impl(TaskObj *self, PyObject *exc)
/*[clinic end generated code: output=7ed23f0cefd5ae42 input=ada4b2324e5370af]*/ /*[clinic end generated code: output=7ed23f0cefd5ae42 input=1e19a985ace87ca4]*/
{ {
return task_step(self, exc == Py_None ? NULL : exc); return task_step(self, exc == Py_None ? NULL : exc);
} }
@ -1699,12 +1697,12 @@ _asyncio_Task__step_impl(TaskObj *self, PyObject *exc)
/*[clinic input] /*[clinic input]
_asyncio.Task._wakeup _asyncio.Task._wakeup
fut: 'O' fut: object
[clinic start generated code]*/ [clinic start generated code]*/
static PyObject * static PyObject *
_asyncio_Task__wakeup_impl(TaskObj *self, PyObject *fut) _asyncio_Task__wakeup_impl(TaskObj *self, PyObject *fut)
/*[clinic end generated code: output=75cb341c760fd071 input=11ee4918a5bdbf21]*/ /*[clinic end generated code: output=75cb341c760fd071 input=6a0616406f829a7b]*/
{ {
return task_wakeup(self, fut); return task_wakeup(self, fut);
} }
@ -1717,11 +1715,9 @@ TaskObj_finalize(TaskObj *task)
_Py_IDENTIFIER(message); _Py_IDENTIFIER(message);
_Py_IDENTIFIER(source_traceback); _Py_IDENTIFIER(source_traceback);
PyObject *context;
PyObject *message = NULL; PyObject *message = NULL;
PyObject *context = NULL; PyObject *func;
PyObject *func = NULL;
PyObject *res = NULL;
PyObject *error_type, *error_value, *error_traceback; PyObject *error_type, *error_value, *error_traceback;
if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) { if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) {
@ -1757,17 +1753,19 @@ TaskObj_finalize(TaskObj *task)
func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler); func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler);
if (func != NULL) { if (func != NULL) {
res = PyObject_CallFunctionObjArgs(func, context, NULL); PyObject *res = PyObject_CallFunctionObjArgs(func, context, NULL);
if (res == NULL) { if (res == NULL) {
PyErr_WriteUnraisable(func); PyErr_WriteUnraisable(func);
} }
else {
Py_DECREF(res);
}
Py_DECREF(func);
} }
finally: finally:
Py_CLEAR(context); Py_XDECREF(context);
Py_CLEAR(message); Py_XDECREF(message);
Py_CLEAR(func);
Py_CLEAR(res);
/* Restore the saved exception. */ /* Restore the saved exception. */
PyErr_Restore(error_type, error_value, error_traceback); PyErr_Restore(error_type, error_value, error_traceback);
@ -1879,9 +1877,6 @@ task_call_step(TaskObj *task, PyObject *arg)
} }
else { else {
/* `task` is a subclass of Task */ /* `task` is a subclass of Task */
if (arg == NULL) {
arg = Py_None;
}
return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__step, return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__step,
arg, NULL); arg, NULL);
} }
@ -1892,7 +1887,7 @@ task_call_step_soon(TaskObj *task, PyObject *arg)
{ {
PyObject *handle; PyObject *handle;
PyObject *cb = TaskSendMethWrapper_new(task, arg); PyObject *cb = TaskStepMethWrapper_new(task, arg);
if (cb == NULL) { if (cb == NULL) {
return -1; return -1;
} }
@ -1947,7 +1942,7 @@ task_step_impl(TaskObj *task, PyObject *exc)
int res; int res;
int clear_exc = 0; int clear_exc = 0;
PyObject *result = NULL; PyObject *result = NULL;
PyObject *coro = task->task_coro; PyObject *coro;
PyObject *o; PyObject *o;
if (task->task_state != STATE_PENDING) { if (task->task_state != STATE_PENDING) {
@ -1988,6 +1983,12 @@ task_step_impl(TaskObj *task, PyObject *exc)
Py_CLEAR(task->task_fut_waiter); Py_CLEAR(task->task_fut_waiter);
coro = task->task_coro;
if (coro == NULL) {
PyErr_SetString(PyExc_RuntimeError, "uninitialized Task object");
return NULL;
}
if (exc == NULL) { if (exc == NULL) {
if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) { if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) {
result = _PyGen_Send((PyGenObject*)coro, Py_None); result = _PyGen_Send((PyGenObject*)coro, Py_None);
@ -2002,7 +2003,7 @@ task_step_impl(TaskObj *task, PyObject *exc)
exc, NULL); exc, NULL);
if (clear_exc) { if (clear_exc) {
/* We created 'exc' during this call */ /* We created 'exc' during this call */
Py_CLEAR(exc); Py_DECREF(exc);
} }
} }
@ -2051,13 +2052,13 @@ set_exception:
o = future_set_exception((FutureObj*)task, ev); o = future_set_exception((FutureObj*)task, ev);
if (!o) { if (!o) {
/* An exception in Task.set_exception() */ /* An exception in Task.set_exception() */
Py_XDECREF(et); Py_DECREF(et);
Py_XDECREF(tb); Py_XDECREF(tb);
Py_XDECREF(ev); Py_XDECREF(ev);
goto fail; goto fail;
} }
assert(o == Py_None); assert(o == Py_None);
Py_CLEAR(o); Py_DECREF(o);
if (!PyErr_GivenExceptionMatches(et, PyExc_Exception)) { if (!PyErr_GivenExceptionMatches(et, PyExc_Exception)) {
/* We've got a BaseException; re-raise it */ /* We've got a BaseException; re-raise it */
@ -2065,7 +2066,7 @@ set_exception:
goto fail; goto fail;
} }
Py_XDECREF(et); Py_DECREF(et);
Py_XDECREF(tb); Py_XDECREF(tb);
Py_XDECREF(ev); Py_XDECREF(ev);
@ -2137,7 +2138,7 @@ set_exception:
} }
else { else {
if (o == Py_None) { if (o == Py_None) {
Py_CLEAR(o); Py_DECREF(o);
} }
else { else {
/* `result` is a Future-compatible object */ /* `result` is a Future-compatible object */
@ -2145,7 +2146,7 @@ set_exception:
PyObject *res; PyObject *res;
int blocking = PyObject_IsTrue(o); int blocking = PyObject_IsTrue(o);
Py_CLEAR(o); Py_DECREF(o);
if (blocking < 0) { if (blocking < 0) {
goto fail; goto fail;
} }
@ -2228,7 +2229,7 @@ set_exception:
goto fail; goto fail;
} }
res = PyObject_IsTrue(o); res = PyObject_IsTrue(o);
Py_CLEAR(o); Py_DECREF(o);
if (res == -1) { if (res == -1) {
/* An exception while checking if 'val' is True */ /* An exception while checking if 'val' is True */
goto fail; goto fail;
@ -2296,14 +2297,8 @@ task_step(TaskObj *task, PyObject *exc)
PyObject *et, *ev, *tb; PyObject *et, *ev, *tb;
PyErr_Fetch(&et, &ev, &tb); PyErr_Fetch(&et, &ev, &tb);
ot = _PyDict_Pop(current_tasks, task->task_loop, NULL); ot = _PyDict_Pop(current_tasks, task->task_loop, NULL);
if (ot == NULL) { Py_XDECREF(ot);
Py_XDECREF(et); _PyErr_ChainExceptions(et, ev, tb);
Py_XDECREF(tb);
Py_XDECREF(ev);
return NULL;
}
Py_DECREF(ot);
PyErr_Restore(et, ev, tb);
return NULL; return NULL;
} }
else { else {
@ -2322,17 +2317,18 @@ task_step(TaskObj *task, PyObject *exc)
static PyObject * static PyObject *
task_wakeup(TaskObj *task, PyObject *o) task_wakeup(TaskObj *task, PyObject *o)
{ {
PyObject *et, *ev, *tb;
PyObject *result;
assert(o); assert(o);
if (Future_CheckExact(o) || Task_CheckExact(o)) { if (Future_CheckExact(o) || Task_CheckExact(o)) {
PyObject *fut_result = NULL; PyObject *fut_result = NULL;
int res = future_get_result((FutureObj*)o, &fut_result); int res = future_get_result((FutureObj*)o, &fut_result);
PyObject *result;
switch(res) { switch(res) {
case -1: case -1:
assert(fut_result == NULL); assert(fut_result == NULL);
return NULL; break; /* exception raised */
case 0: case 0:
Py_DECREF(fut_result); Py_DECREF(fut_result);
return task_call_step(task, NULL); return task_call_step(task, NULL);
@ -2343,29 +2339,32 @@ task_wakeup(TaskObj *task, PyObject *o)
return result; return result;
} }
} }
PyObject *fut_result = PyObject_CallMethod(o, "result", NULL);
if (fut_result == NULL) {
PyObject *et, *ev, *tb;
PyObject *res;
PyErr_Fetch(&et, &ev, &tb);
if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
PyErr_NormalizeException(&et, &ev, &tb);
}
res = task_call_step(task, ev);
Py_XDECREF(et);
Py_XDECREF(tb);
Py_XDECREF(ev);
return res;
}
else { else {
Py_DECREF(fut_result); PyObject *fut_result = PyObject_CallMethod(o, "result", NULL);
return task_call_step(task, NULL); if (fut_result != NULL) {
Py_DECREF(fut_result);
return task_call_step(task, NULL);
}
/* exception raised */
} }
PyErr_Fetch(&et, &ev, &tb);
if (!PyErr_GivenExceptionMatches(et, PyExc_Exception)) {
/* We've got a BaseException; re-raise it */
PyErr_Restore(et, ev, tb);
return NULL;
}
if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
PyErr_NormalizeException(&et, &ev, &tb);
}
result = task_call_step(task, ev);
Py_DECREF(et);
Py_XDECREF(tb);
Py_XDECREF(ev);
return result;
} }
@ -2398,7 +2397,7 @@ module_init(void)
Py_CLEAR(module); \ Py_CLEAR(module); \
module = PyImport_ImportModule(NAME); \ module = PyImport_ImportModule(NAME); \
if (module == NULL) { \ if (module == NULL) { \
return -1; \ goto fail; \
} }
#define GET_MOD_ATTR(VAR, NAME) \ #define GET_MOD_ATTR(VAR, NAME) \
@ -2429,7 +2428,7 @@ module_init(void)
WITH_MOD("weakref") WITH_MOD("weakref")
GET_MOD_ATTR(cls, "WeakSet") GET_MOD_ATTR(cls, "WeakSet")
all_tasks = _PyObject_CallNoArg(cls); all_tasks = _PyObject_CallNoArg(cls);
Py_CLEAR(cls); Py_DECREF(cls);
if (all_tasks == NULL) { if (all_tasks == NULL) {
goto fail; goto fail;
} }
@ -2439,7 +2438,7 @@ module_init(void)
goto fail; goto fail;
} }
Py_CLEAR(module); Py_DECREF(module);
return 0; return 0;
fail: fail:
@ -2478,7 +2477,7 @@ PyInit__asyncio(void)
if (PyType_Ready(&FutureIterType) < 0) { if (PyType_Ready(&FutureIterType) < 0) {
return NULL; return NULL;
} }
if (PyType_Ready(&TaskSendMethWrapper_Type) < 0) { if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) {
return NULL; return NULL;
} }
if(PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) { if(PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) {

View File

@ -28,7 +28,7 @@ _asyncio_Future___init__(PyObject *self, PyObject *args, PyObject *kwargs)
int return_value = -1; int return_value = -1;
static const char * const _keywords[] = {"loop", NULL}; static const char * const _keywords[] = {"loop", NULL};
static _PyArg_Parser _parser = {"|$O:Future", _keywords, 0}; static _PyArg_Parser _parser = {"|$O:Future", _keywords, 0};
PyObject *loop = NULL; PyObject *loop = Py_None;
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
&loop)) { &loop)) {
@ -244,7 +244,7 @@ _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs)
static const char * const _keywords[] = {"coro", "loop", NULL}; static const char * const _keywords[] = {"coro", "loop", NULL};
static _PyArg_Parser _parser = {"O|$O:Task", _keywords, 0}; static _PyArg_Parser _parser = {"O|$O:Task", _keywords, 0};
PyObject *coro; PyObject *coro;
PyObject *loop = NULL; PyObject *loop = Py_None;
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
&coro, &loop)) { &coro, &loop)) {
@ -477,7 +477,7 @@ _asyncio_Task__step(TaskObj *self, PyObject **args, Py_ssize_t nargs, PyObject *
PyObject *return_value = NULL; PyObject *return_value = NULL;
static const char * const _keywords[] = {"exc", NULL}; static const char * const _keywords[] = {"exc", NULL};
static _PyArg_Parser _parser = {"|O:_step", _keywords, 0}; static _PyArg_Parser _parser = {"|O:_step", _keywords, 0};
PyObject *exc = NULL; PyObject *exc = Py_None;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
&exc)) { &exc)) {
@ -517,4 +517,4 @@ _asyncio_Task__wakeup(TaskObj *self, PyObject **args, Py_ssize_t nargs, PyObject
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=fe651840e0466fa9 input=a9049054013a1b77]*/ /*[clinic end generated code: output=b92f9cd2b9fb37ef input=a9049054013a1b77]*/