diff options
author | INADA Naoki <songofacandy@gmail.com> | 2016-10-15 15:39:19 +0900 |
---|---|---|
committer | INADA Naoki <songofacandy@gmail.com> | 2016-10-15 15:39:19 +0900 |
commit | 9f2ce2548107eedaf0970546a508c33d24920622 (patch) | |
tree | 2a410ccb15a3acb857985a3ce15e71fc7bdc3cda /Modules/_futuresmodule.c | |
parent | 479eb760f4dd5ae5cfc5ccf8a361cdea3d48624a (diff) | |
download | cpython-git-9f2ce2548107eedaf0970546a508c33d24920622.tar.gz |
Issue #28428: Rename _futures module to _asyncio.
It will have more speedup functions or classes other than asyncio.Future.
Diffstat (limited to 'Modules/_futuresmodule.c')
-rw-r--r-- | Modules/_futuresmodule.c | 1034 |
1 files changed, 0 insertions, 1034 deletions
diff --git a/Modules/_futuresmodule.c b/Modules/_futuresmodule.c deleted file mode 100644 index 3e91a3c8b8..0000000000 --- a/Modules/_futuresmodule.c +++ /dev/null @@ -1,1034 +0,0 @@ -#include "Python.h" -#include "structmember.h" - - -/* identifiers used from some functions */ -_Py_IDENTIFIER(call_soon); - - -/* State of the _futures module */ -static int _futuremod_ready; -static PyObject *traceback_extract_stack; -static PyObject *asyncio_get_event_loop; -static PyObject *asyncio_repr_info_func; -static PyObject *asyncio_InvalidStateError; -static PyObject *asyncio_CancelledError; - - -/* Get FutureIter from Future */ -static PyObject* new_future_iter(PyObject *fut); - - -/* make sure module state is initialized and ready to be used. */ -static int -_FuturesMod_EnsureState(void) -{ - if (!_futuremod_ready) { - PyErr_SetString(PyExc_RuntimeError, - "_futures module wasn't properly initialized"); - return -1; - } - return 0; -} - - -typedef enum { - STATE_PENDING, - STATE_CANCELLED, - STATE_FINISHED -} fut_state; - - -typedef struct { - PyObject_HEAD - PyObject *fut_loop; - PyObject *fut_callbacks; - PyObject *fut_exception; - PyObject *fut_result; - PyObject *fut_source_tb; - fut_state fut_state; - int fut_log_tb; - int fut_blocking; - PyObject *dict; - PyObject *fut_weakreflist; -} FutureObj; - - -static int -_schedule_callbacks(FutureObj *fut) -{ - Py_ssize_t len; - PyObject* iters; - int i; - - if (fut->fut_callbacks == NULL) { - PyErr_SetString(PyExc_RuntimeError, "NULL callbacks"); - return -1; - } - - len = PyList_GET_SIZE(fut->fut_callbacks); - if (len == 0) { - return 0; - } - - iters = PyList_GetSlice(fut->fut_callbacks, 0, len); - if (iters == NULL) { - return -1; - } - if (PyList_SetSlice(fut->fut_callbacks, 0, len, NULL) < 0) { - Py_DECREF(iters); - return -1; - } - - for (i = 0; i < len; i++) { - PyObject *handle = NULL; - PyObject *cb = PyList_GET_ITEM(iters, i); - - handle = _PyObject_CallMethodId( - fut->fut_loop, &PyId_call_soon, "OO", cb, fut, NULL); - - if (handle == NULL) { - Py_DECREF(iters); - return -1; - } - else { - Py_DECREF(handle); - } - } - - Py_DECREF(iters); - return 0; -} - -static int -FutureObj_init(FutureObj *fut, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"loop", NULL}; - PyObject *loop = NULL; - PyObject *res = NULL; - _Py_IDENTIFIER(get_debug); - - if (_FuturesMod_EnsureState()) { - return -1; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$O", kwlist, &loop)) { - return -1; - } - if (loop == NULL || loop == Py_None) { - loop = PyObject_CallObject(asyncio_get_event_loop, NULL); - if (loop == NULL) { - return -1; - } - } - else { - Py_INCREF(loop); - } - Py_CLEAR(fut->fut_loop); - fut->fut_loop = loop; - - res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, "()", NULL); - if (res == NULL) { - return -1; - } - if (PyObject_IsTrue(res)) { - Py_CLEAR(res); - fut->fut_source_tb = PyObject_CallObject(traceback_extract_stack, NULL); - if (fut->fut_source_tb == NULL) { - return -1; - } - } - else { - Py_CLEAR(res); - } - - fut->fut_callbacks = PyList_New(0); - if (fut->fut_callbacks == NULL) { - return -1; - } - return 0; -} - -static int -FutureObj_clear(FutureObj *fut) -{ - Py_CLEAR(fut->fut_loop); - Py_CLEAR(fut->fut_callbacks); - Py_CLEAR(fut->fut_result); - Py_CLEAR(fut->fut_exception); - Py_CLEAR(fut->fut_source_tb); - Py_CLEAR(fut->dict); - return 0; -} - -static int -FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg) -{ - Py_VISIT(fut->fut_loop); - Py_VISIT(fut->fut_callbacks); - Py_VISIT(fut->fut_result); - Py_VISIT(fut->fut_exception); - Py_VISIT(fut->fut_source_tb); - Py_VISIT(fut->dict); - return 0; -} - -PyDoc_STRVAR(pydoc_result, - "Return the result this future represents.\n" - "\n" - "If the future has been cancelled, raises CancelledError. If the\n" - "future's result isn't yet available, raises InvalidStateError. If\n" - "the future is done and has an exception set, this exception is raised." -); - -static PyObject * -FutureObj_result(FutureObj *fut, PyObject *arg) -{ - if (fut->fut_state == STATE_CANCELLED) { - PyErr_SetString(asyncio_CancelledError, ""); - return NULL; - } - - if (fut->fut_state != STATE_FINISHED) { - PyErr_SetString(asyncio_InvalidStateError, "Result is not ready."); - return NULL; - } - - fut->fut_log_tb = 0; - if (fut->fut_exception != NULL) { - PyObject *type = NULL; - type = PyExceptionInstance_Class(fut->fut_exception); - PyErr_SetObject(type, fut->fut_exception); - return NULL; - } - - Py_INCREF(fut->fut_result); - return fut->fut_result; -} - -PyDoc_STRVAR(pydoc_exception, - "Return the exception that was set on this future.\n" - "\n" - "The exception (or None if no exception was set) is returned only if\n" - "the future is done. If the future has been cancelled, raises\n" - "CancelledError. If the future isn't done yet, raises\n" - "InvalidStateError." -); - -static PyObject * -FutureObj_exception(FutureObj *fut, PyObject *arg) -{ - if (_FuturesMod_EnsureState()) { - return NULL; - } - - if (fut->fut_state == STATE_CANCELLED) { - PyErr_SetString(asyncio_CancelledError, ""); - return NULL; - } - - if (fut->fut_state != STATE_FINISHED) { - PyErr_SetString(asyncio_InvalidStateError, "Result is not ready."); - return NULL; - } - - if (fut->fut_exception != NULL) { - fut->fut_log_tb = 0; - Py_INCREF(fut->fut_exception); - return fut->fut_exception; - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(pydoc_set_result, - "Mark the future done and set its result.\n" - "\n" - "If the future is already done when this method is called, raises\n" - "InvalidStateError." -); - -static PyObject * -FutureObj_set_result(FutureObj *fut, PyObject *res) -{ - if (_FuturesMod_EnsureState()) { - return NULL; - } - - if (fut->fut_state != STATE_PENDING) { - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); - return NULL; - } - - Py_INCREF(res); - fut->fut_result = res; - fut->fut_state = STATE_FINISHED; - - if (_schedule_callbacks(fut) == -1) { - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(pydoc_set_exception, - "Mark the future done and set an exception.\n" - "\n" - "If the future is already done when this method is called, raises\n" - "InvalidStateError." -); - -static PyObject * -FutureObj_set_exception(FutureObj *fut, PyObject *exc) -{ - PyObject *exc_val = NULL; - - if (_FuturesMod_EnsureState()) { - return NULL; - } - - if (fut->fut_state != STATE_PENDING) { - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); - return NULL; - } - - if (PyExceptionClass_Check(exc)) { - exc_val = PyObject_CallObject(exc, NULL); - if (exc_val == NULL) { - return NULL; - } - } - else { - exc_val = exc; - Py_INCREF(exc_val); - } - if (!PyExceptionInstance_Check(exc_val)) { - Py_DECREF(exc_val); - PyErr_SetString(PyExc_TypeError, "invalid exception object"); - return NULL; - } - if ((PyObject*)Py_TYPE(exc_val) == PyExc_StopIteration) { - Py_DECREF(exc_val); - PyErr_SetString(PyExc_TypeError, - "StopIteration interacts badly with generators " - "and cannot be raised into a Future"); - return NULL; - } - - fut->fut_exception = exc_val; - fut->fut_state = STATE_FINISHED; - - if (_schedule_callbacks(fut) == -1) { - return NULL; - } - - fut->fut_log_tb = 1; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(pydoc_add_done_callback, - "Add a callback to be run when the future becomes done.\n" - "\n" - "The callback is called with a single argument - the future object. If\n" - "the future is already done when this is called, the callback is\n" - "scheduled with call_soon."; -); - -static PyObject * -FutureObj_add_done_callback(FutureObj *fut, PyObject *arg) -{ - if (fut->fut_state != STATE_PENDING) { - PyObject *handle = _PyObject_CallMethodId( - fut->fut_loop, &PyId_call_soon, "OO", arg, fut, NULL); - - if (handle == NULL) { - return NULL; - } - else { - Py_DECREF(handle); - } - } - else { - int err = PyList_Append(fut->fut_callbacks, arg); - if (err != 0) { - return NULL; - } - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(pydoc_remove_done_callback, - "Remove all instances of a callback from the \"call when done\" list.\n" - "\n" - "Returns the number of callbacks removed." -); - -static PyObject * -FutureObj_remove_done_callback(FutureObj *fut, PyObject *arg) -{ - PyObject *newlist; - Py_ssize_t len, i, j=0; - - len = PyList_GET_SIZE(fut->fut_callbacks); - if (len == 0) { - return PyLong_FromSsize_t(0); - } - - newlist = PyList_New(len); - if (newlist == NULL) { - return NULL; - } - - for (i = 0; i < len; i++) { - int ret; - PyObject *item = PyList_GET_ITEM(fut->fut_callbacks, i); - - if ((ret = PyObject_RichCompareBool(arg, item, Py_EQ)) < 0) { - goto fail; - } - if (ret == 0) { - Py_INCREF(item); - PyList_SET_ITEM(newlist, j, item); - j++; - } - } - - if (PyList_SetSlice(newlist, j, len, NULL) < 0) { - goto fail; - } - if (PyList_SetSlice(fut->fut_callbacks, 0, len, newlist) < 0) { - goto fail; - } - Py_DECREF(newlist); - return PyLong_FromSsize_t(len - j); - -fail: - Py_DECREF(newlist); - return NULL; -} - -PyDoc_STRVAR(pydoc_cancel, - "Cancel the future and schedule callbacks.\n" - "\n" - "If the future is already done or cancelled, return False. Otherwise,\n" - "change the future's state to cancelled, schedule the callbacks and\n" - "return True." -); - -static PyObject * -FutureObj_cancel(FutureObj *fut, PyObject *arg) -{ - if (fut->fut_state != STATE_PENDING) { - Py_RETURN_FALSE; - } - fut->fut_state = STATE_CANCELLED; - - if (_schedule_callbacks(fut) == -1) { - return NULL; - } - - Py_RETURN_TRUE; -} - -PyDoc_STRVAR(pydoc_cancelled, "Return True if the future was cancelled."); - -static PyObject * -FutureObj_cancelled(FutureObj *fut, PyObject *arg) -{ - if (fut->fut_state == STATE_CANCELLED) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -PyDoc_STRVAR(pydoc_done, - "Return True if the future is done.\n" - "\n" - "Done means either that a result / exception are available, or that the\n" - "future was cancelled." -); - -static PyObject * -FutureObj_done(FutureObj *fut, PyObject *arg) -{ - if (fut->fut_state == STATE_PENDING) { - Py_RETURN_FALSE; - } - else { - Py_RETURN_TRUE; - } -} - -static PyObject * -FutureObj_get_blocking(FutureObj *fut) -{ - if (fut->fut_blocking) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -static int -FutureObj_set_blocking(FutureObj *fut, PyObject *val) -{ - int is_true = PyObject_IsTrue(val); - if (is_true < 0) { - return -1; - } - fut->fut_blocking = is_true; - return 0; -} - -static PyObject * -FutureObj_get_log_traceback(FutureObj *fut) -{ - if (fut->fut_log_tb) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -static PyObject * -FutureObj_get_loop(FutureObj *fut) -{ - if (fut->fut_loop == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_loop); - return fut->fut_loop; -} - -static PyObject * -FutureObj_get_callbacks(FutureObj *fut) -{ - if (fut->fut_callbacks == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_callbacks); - return fut->fut_callbacks; -} - -static PyObject * -FutureObj_get_result(FutureObj *fut) -{ - if (fut->fut_result == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_result); - return fut->fut_result; -} - -static PyObject * -FutureObj_get_exception(FutureObj *fut) -{ - if (fut->fut_exception == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_exception); - return fut->fut_exception; -} - -static PyObject * -FutureObj_get_source_traceback(FutureObj *fut) -{ - if (fut->fut_source_tb == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_source_tb); - return fut->fut_source_tb; -} - -static PyObject * -FutureObj_get_state(FutureObj *fut) -{ - _Py_IDENTIFIER(PENDING); - _Py_IDENTIFIER(CANCELLED); - _Py_IDENTIFIER(FINISHED); - PyObject *ret = NULL; - - switch (fut->fut_state) { - case STATE_PENDING: - ret = _PyUnicode_FromId(&PyId_PENDING); - break; - case STATE_CANCELLED: - ret = _PyUnicode_FromId(&PyId_CANCELLED); - break; - case STATE_FINISHED: - ret = _PyUnicode_FromId(&PyId_FINISHED); - break; - default: - assert (0); - } - Py_INCREF(ret); - return ret; -} - -static PyObject* -FutureObj__repr_info(FutureObj *fut) -{ - if (asyncio_repr_info_func == NULL) { - return PyList_New(0); - } - return PyObject_CallFunctionObjArgs(asyncio_repr_info_func, fut, NULL); -} - -static PyObject * -FutureObj_repr(FutureObj *fut) -{ - _Py_IDENTIFIER(_repr_info); - - PyObject *_repr_info = _PyUnicode_FromId(&PyId__repr_info); // borrowed - if (_repr_info == NULL) { - return NULL; - } - - PyObject *rinfo = PyObject_CallMethodObjArgs((PyObject*)fut, _repr_info, - NULL); - if (rinfo == NULL) { - return NULL; - } - - PyObject *sp = PyUnicode_FromString(" "); - if (sp == NULL) { - Py_DECREF(rinfo); - return NULL; - } - - PyObject *rinfo_s = PyUnicode_Join(sp, rinfo); - Py_DECREF(sp); - Py_DECREF(rinfo); - if (rinfo_s == NULL) { - return NULL; - } - - PyObject *rstr = NULL; - PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), - "__name__"); - if (type_name != NULL) { - rstr = PyUnicode_FromFormat("<%S %S>", type_name, rinfo_s); - Py_DECREF(type_name); - } - Py_DECREF(rinfo_s); - return rstr; -} - -static void -FutureObj_finalize(FutureObj *fut) -{ - _Py_IDENTIFIER(call_exception_handler); - _Py_IDENTIFIER(message); - _Py_IDENTIFIER(exception); - _Py_IDENTIFIER(future); - _Py_IDENTIFIER(source_traceback); - - if (!fut->fut_log_tb) { - return; - } - assert(fut->fut_exception != NULL); - fut->fut_log_tb = 0;; - - PyObject *error_type, *error_value, *error_traceback; - /* Save the current exception, if any. */ - 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(); - if (context == NULL) { - goto finally; - } - - type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), "__name__"); - if (type_name == NULL) { - goto finally; - } - - message = PyUnicode_FromFormat( - "%S exception was never retrieved", type_name); - if (message == NULL) { - goto finally; - } - - if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || - _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 || - _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) { - goto finally; - } - if (fut->fut_source_tb != NULL) { - if (_PyDict_SetItemId(context, &PyId_source_traceback, - fut->fut_source_tb) < 0) { - goto finally; - } - } - - func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler); - if (func != NULL) { - res = _PyObject_CallArg1(func, context); - if (res == NULL) { - PyErr_WriteUnraisable(func); - } - } - -finally: - Py_CLEAR(context); - Py_CLEAR(type_name); - Py_CLEAR(message); - Py_CLEAR(func); - Py_CLEAR(res); - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); -} - - -static PyAsyncMethods FutureType_as_async = { - (unaryfunc)new_future_iter, /* am_await */ - 0, /* am_aiter */ - 0 /* am_anext */ -}; - -static PyMethodDef FutureType_methods[] = { - {"_repr_info", (PyCFunction)FutureObj__repr_info, METH_NOARGS, NULL}, - {"add_done_callback", - (PyCFunction)FutureObj_add_done_callback, - METH_O, pydoc_add_done_callback}, - {"remove_done_callback", - (PyCFunction)FutureObj_remove_done_callback, - METH_O, pydoc_remove_done_callback}, - {"set_result", - (PyCFunction)FutureObj_set_result, METH_O, pydoc_set_result}, - {"set_exception", - (PyCFunction)FutureObj_set_exception, METH_O, pydoc_set_exception}, - {"cancel", (PyCFunction)FutureObj_cancel, METH_NOARGS, pydoc_cancel}, - {"cancelled", - (PyCFunction)FutureObj_cancelled, METH_NOARGS, pydoc_cancelled}, - {"done", (PyCFunction)FutureObj_done, METH_NOARGS, pydoc_done}, - {"result", (PyCFunction)FutureObj_result, METH_NOARGS, pydoc_result}, - {"exception", - (PyCFunction)FutureObj_exception, METH_NOARGS, pydoc_exception}, - {NULL, NULL} /* Sentinel */ -}; - -static PyGetSetDef FutureType_getsetlist[] = { - {"_state", (getter)FutureObj_get_state, NULL, NULL}, - {"_asyncio_future_blocking", (getter)FutureObj_get_blocking, - (setter)FutureObj_set_blocking, NULL}, - {"_loop", (getter)FutureObj_get_loop, NULL, NULL}, - {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL}, - {"_result", (getter)FutureObj_get_result, NULL, NULL}, - {"_exception", (getter)FutureObj_get_exception, NULL, NULL}, - {"_log_traceback", (getter)FutureObj_get_log_traceback, NULL, NULL}, - {"_source_traceback", (getter)FutureObj_get_source_traceback, NULL, NULL}, - {NULL} /* Sentinel */ -}; - -static void FutureObj_dealloc(PyObject *self); - -static PyTypeObject FutureType = { - PyVarObject_HEAD_INIT(0, 0) - "_futures.Future", - sizeof(FutureObj), /* tp_basicsize */ - .tp_dealloc = FutureObj_dealloc, - .tp_as_async = &FutureType_as_async, - .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, - .tp_doc = "Fast asyncio.Future implementation.", - .tp_traverse = (traverseproc)FutureObj_traverse, - .tp_clear = (inquiry)FutureObj_clear, - .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist), - .tp_iter = (getiterfunc)new_future_iter, - .tp_methods = FutureType_methods, - .tp_getset = FutureType_getsetlist, - .tp_dictoffset = offsetof(FutureObj, dict), - .tp_init = (initproc)FutureObj_init, - .tp_new = PyType_GenericNew, - .tp_finalize = (destructor)FutureObj_finalize, -}; - -static void -FutureObj_dealloc(PyObject *self) -{ - FutureObj *fut = (FutureObj *)self; - - if (Py_TYPE(fut) == &FutureType) { - /* When fut is subclass of Future, finalizer is called from - * subtype_dealloc. - */ - if (PyObject_CallFinalizerFromDealloc(self) < 0) { - // resurrected. - return; - } - } - - if (fut->fut_weakreflist != NULL) { - PyObject_ClearWeakRefs(self); - } - - FutureObj_clear(fut); - Py_TYPE(fut)->tp_free(fut); -} - - -/*********************** Future Iterator **************************/ - -typedef struct { - PyObject_HEAD - FutureObj *future; -} futureiterobject; - -static void -FutureIter_dealloc(futureiterobject *it) -{ - _PyObject_GC_UNTRACK(it); - Py_XDECREF(it->future); - PyObject_GC_Del(it); -} - -static PyObject * -FutureIter_iternext(futureiterobject *it) -{ - PyObject *res; - FutureObj *fut = it->future; - - if (fut == NULL) { - return NULL; - } - - if (fut->fut_state == STATE_PENDING) { - if (!fut->fut_blocking) { - fut->fut_blocking = 1; - Py_INCREF(fut); - return (PyObject *)fut; - } - PyErr_Format(PyExc_AssertionError, - "yield from wasn't used with future"); - return NULL; - } - - res = FutureObj_result(fut, NULL); - if (res != NULL) { - // normal result - PyErr_SetObject(PyExc_StopIteration, res); - Py_DECREF(res); - } - - it->future = NULL; - Py_DECREF(fut); - return NULL; -} - -static PyObject * -FutureIter_send(futureiterobject *self, PyObject *arg) -{ - if (arg != Py_None) { - PyErr_Format(PyExc_TypeError, - "can't send non-None value to a FutureIter"); - return NULL; - } - return FutureIter_iternext(self); -} - -static PyObject * -FutureIter_throw(futureiterobject *self, PyObject *args) -{ - PyObject *type=NULL, *val=NULL, *tb=NULL; - if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb)) - return NULL; - - if (val == Py_None) { - val = NULL; - } - if (tb == Py_None) { - tb = NULL; - } - - Py_CLEAR(self->future); - - if (tb != NULL) { - PyErr_Restore(type, val, tb); - } - else if (val != NULL) { - PyErr_SetObject(type, val); - } - else { - if (PyExceptionClass_Check(type)) { - val = PyObject_CallObject(type, NULL); - } - else { - val = type; - assert (PyExceptionInstance_Check(val)); - type = (PyObject*)Py_TYPE(val); - assert (PyExceptionClass_Check(type)); - } - PyErr_SetObject(type, val); - } - return FutureIter_iternext(self); -} - -static PyObject * -FutureIter_close(futureiterobject *self, PyObject *arg) -{ - Py_CLEAR(self->future); - Py_RETURN_NONE; -} - -static int -FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->future); - return 0; -} - -static PyMethodDef FutureIter_methods[] = { - {"send", (PyCFunction)FutureIter_send, METH_O, NULL}, - {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL}, - {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL}, - {NULL, NULL} /* Sentinel */ -}; - -static PyTypeObject FutureIterType = { - PyVarObject_HEAD_INIT(0, 0) - "_futures.FutureIter", - sizeof(futureiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)FutureIter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)FutureIter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)FutureIter_iternext, /* tp_iternext */ - FutureIter_methods, /* tp_methods */ - 0, /* tp_members */ -}; - -static PyObject * -new_future_iter(PyObject *fut) -{ - futureiterobject *it; - - if (!PyObject_TypeCheck(fut, &FutureType)) { - PyErr_BadInternalCall(); - return NULL; - } - it = PyObject_GC_New(futureiterobject, &FutureIterType); - if (it == NULL) { - return NULL; - } - Py_INCREF(fut); - it->future = (FutureObj*)fut; - PyObject_GC_Track(it); - return (PyObject*)it; -} - -/*********************** Module **************************/ - -PyDoc_STRVAR(module_doc, "Fast asyncio.Future implementation.\n"); - -PyObject * -_init_module(PyObject *self, PyObject *args) -{ - PyObject *extract_stack; - PyObject *get_event_loop; - PyObject *repr_info_func; - PyObject *invalidStateError; - PyObject *cancelledError; - - if (!PyArg_UnpackTuple(args, "_init_module", 5, 5, - &extract_stack, - &get_event_loop, - &repr_info_func, - &invalidStateError, - &cancelledError)) { - return NULL; - } - - Py_INCREF(extract_stack); - Py_XSETREF(traceback_extract_stack, extract_stack); - - Py_INCREF(get_event_loop); - Py_XSETREF(asyncio_get_event_loop, get_event_loop); - - Py_INCREF(repr_info_func); - Py_XSETREF(asyncio_repr_info_func, repr_info_func); - - Py_INCREF(invalidStateError); - Py_XSETREF(asyncio_InvalidStateError, invalidStateError); - - Py_INCREF(cancelledError); - Py_XSETREF(asyncio_CancelledError, cancelledError); - - _futuremod_ready = 1; - - Py_RETURN_NONE; -} - - -static struct PyMethodDef futuresmod_methods[] = { - {"_init_module", _init_module, METH_VARARGS, NULL}, - {NULL, NULL} -}; - - -static struct PyModuleDef _futuresmodule = { - PyModuleDef_HEAD_INIT, /* m_base */ - "_futures", /* m_name */ - module_doc, /* m_doc */ - -1, /* m_size */ - futuresmod_methods, /* m_methods */ - NULL, /* m_slots */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; - - -PyMODINIT_FUNC -PyInit__futures(void) -{ - if (PyType_Ready(&FutureType) < 0) { - return NULL; - } - if (PyType_Ready(&FutureIterType) < 0) { - return NULL; - } - - PyObject *m = PyModule_Create(&_futuresmodule); - if (m == NULL) { - return NULL; - } - - Py_INCREF(&FutureType); - if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) { - Py_DECREF(&FutureType); - return NULL; - } - - return m; -} |