diff -r 738579b25d02 Lib/asyncio/futures.py --- a/Lib/asyncio/futures.py Sun Oct 16 15:42:24 2016 -0700 +++ b/Lib/asyncio/futures.py Mon Oct 17 11:52:24 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 738579b25d02 Modules/_asynciomodule.c --- a/Modules/_asynciomodule.c Sun Oct 16 15:42:24 2016 -0700 +++ b/Modules/_asynciomodule.c Mon Oct 17 11:52:24 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,94 @@ PyObject_GC_Track(it); return (PyObject*)it; } /*********************** Module **************************/ -PyDoc_STRVAR(module_doc, "asyncio speedups.\n"); +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; + 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; + 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); + + 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); + return 0; - Py_INCREF(invalidStateError); - Py_XSETREF(asyncio_InvalidStateError, invalidStateError); - - 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, "Accelerator module for asyncio"); 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; }