diff -r 9d06fdedae2b Lib/asyncio/futures.py --- a/Lib/asyncio/futures.py Sat Oct 15 15:39:19 2016 +0900 +++ b/Lib/asyncio/futures.py Sun Oct 16 05:12:20 2016 +0900 @@ -428,27 +428,12 @@ dest.set_exception(exception) else: result = source.result() dest.set_result(result) -try: - import _asyncio -except ImportError: - pass -else: - _asyncio._init_module( - traceback.extract_stack, - events.get_event_loop, - _future_repr_info, - InvalidStateError, - CancelledError) - - Future = _asyncio.Future - - def _chain_future(source, destination): """Chain two futures so that when one completes, so does the other. The result (or exception) of source will be copied to destination. If destination is cancelled, source gets cancelled too. Compatible with both asyncio.Future and concurrent.futures.Future. @@ -493,6 +478,14 @@ 'concurrent.futures.Future is expected, got {!r}'.format(future) if loop is None: loop = events.get_event_loop() new_future = loop.create_future() _chain_future(future, new_future) return new_future + + +try: + import _asyncio +except ImportError: + pass +else: + Future = _asyncio.Future diff -r 9d06fdedae2b Modules/_asynciomodule.c --- a/Modules/_asynciomodule.c Sat Oct 15 15:39:19 2016 +0900 +++ b/Modules/_asynciomodule.c Sun Oct 16 05:12:20 2016 +0900 @@ -4,37 +4,23 @@ /* identifiers used from some functions */ _Py_IDENTIFIER(call_soon); /* State of the _asyncio module */ -static int _asynciomod_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 -_AsyncioMod_EnsureState(void) -{ - if (!_asynciomod_ready) { - PyErr_SetString(PyExc_RuntimeError, - "_asyncio module wasn't properly initialized"); - return -1; - } - return 0; -} - - typedef enum { STATE_PENDING, STATE_CANCELLED, STATE_FINISHED } fut_state; @@ -105,16 +91,12 @@ { static char *kwlist[] = {"loop", NULL}; PyObject *loop = NULL; PyObject *res = NULL; _Py_IDENTIFIER(get_debug); - if (_AsyncioMod_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) { @@ -215,16 +197,12 @@ "InvalidStateError." ); static PyObject * FutureObj_exception(FutureObj *fut, PyObject *arg) { - if (_AsyncioMod_EnsureState()) { - return NULL; - } - if (fut->fut_state == STATE_CANCELLED) { PyErr_SetString(asyncio_CancelledError, ""); return NULL; } if (fut->fut_state != STATE_FINISHED) { @@ -248,16 +226,12 @@ "InvalidStateError." ); static PyObject * FutureObj_set_result(FutureObj *fut, PyObject *res) { - if (_AsyncioMod_EnsureState()) { - return NULL; - } - if (fut->fut_state != STATE_PENDING) { PyErr_SetString(asyncio_InvalidStateError, "invalid state"); return NULL; } Py_INCREF(res); @@ -279,16 +253,12 @@ static PyObject * FutureObj_set_exception(FutureObj *fut, PyObject *exc) { PyObject *exc_val = NULL; - if (_AsyncioMod_EnsureState()) { - return NULL; - } - if (fut->fut_state != STATE_PENDING) { PyErr_SetString(asyncio_InvalidStateError, "invalid state"); return NULL; } if (PyExceptionClass_Check(exc)) { @@ -946,75 +916,102 @@ PyObject_GC_Track(it); return (PyObject*)it; } /*********************** Module **************************/ -PyDoc_STRVAR(module_doc, "asyncio speedups.\n"); +// Imports external dependencies. +static int +init_module(void) +{ + PyObject *module = NULL; -PyObject * -_init_module(PyObject *self, PyObject *args) -{ - PyObject *extract_stack; - PyObject *get_event_loop; - PyObject *repr_info_func; - PyObject *invalidStateError; - PyObject *cancelledError; + // from traceback import extract_stack + module = PyImport_ImportModule("traceback"); + if (module == NULL) { + return -1; + } + // new reference + traceback_extract_stack = PyObject_GetAttrString(module, "extract_stack"); + if (traceback_extract_stack == NULL) { + goto fail; + } + Py_DECREF(module); - if (!PyArg_UnpackTuple(args, "_init_module", 5, 5, - &extract_stack, - &get_event_loop, - &repr_info_func, - &invalidStateError, - &cancelledError)) { - return NULL; + // from asyncio.events import get_event_loop + module = PyImport_ImportModule("asyncio.events"); + if (module == NULL) { + goto fail; + } + asyncio_get_event_loop = PyObject_GetAttrString(module, "get_event_loop"); + if (asyncio_get_event_loop == NULL) { + goto fail; + } + Py_DECREF(module); + + /* from asyncio.futures import _future_repr_info, + * InvalidStateError, + * CancelledError + */ + module = PyImport_ImportModule("asyncio.futures"); + if (module == NULL) { + goto fail; + } + asyncio_repr_info_func = PyObject_GetAttrString(module, + "_future_repr_info"); + if (asyncio_repr_info_func == NULL) { + goto fail; } - Py_INCREF(extract_stack); - Py_XSETREF(traceback_extract_stack, extract_stack); + asyncio_InvalidStateError = PyObject_GetAttrString(module, + "InvalidStateError"); + if (asyncio_InvalidStateError == NULL) { + goto fail; + } - Py_INCREF(get_event_loop); - Py_XSETREF(asyncio_get_event_loop, get_event_loop); + asyncio_CancelledError = PyObject_GetAttrString(module, "CancelledError"); + if (asyncio_CancelledError == NULL) { + goto fail; + } - Py_INCREF(repr_info_func); - Py_XSETREF(asyncio_repr_info_func, repr_info_func); + Py_DECREF(module); - Py_INCREF(invalidStateError); - Py_XSETREF(asyncio_InvalidStateError, invalidStateError); + return 0; - Py_INCREF(cancelledError); - Py_XSETREF(asyncio_CancelledError, cancelledError); - - _asynciomod_ready = 1; - - Py_RETURN_NONE; +fail: + Py_CLEAR(traceback_extract_stack); + Py_CLEAR(asyncio_get_event_loop); + Py_CLEAR(asyncio_repr_info_func); + Py_CLEAR(asyncio_InvalidStateError); + Py_CLEAR(asyncio_CancelledError); + Py_CLEAR(module); + return -1; } -static struct PyMethodDef asynciomod_methods[] = { - {"_init_module", _init_module, METH_VARARGS, NULL}, - {NULL, NULL} -}; - +PyDoc_STRVAR(module_doc, "asyncio speedups.\n"); static struct PyModuleDef _asynciomodule = { PyModuleDef_HEAD_INIT, /* m_base */ "_asyncio", /* m_name */ module_doc, /* m_doc */ -1, /* m_size */ - asynciomod_methods, /* m_methods */ + NULL, /* m_methods */ NULL, /* m_slots */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }; PyMODINIT_FUNC PyInit__asyncio(void) { + if (init_module() < 0) { + return NULL; + } if (PyType_Ready(&FutureType) < 0) { return NULL; } if (PyType_Ready(&FutureIterType) < 0) { return NULL; }