From c411a7d8210febfbe96a2547357752be6be7adad Mon Sep 17 00:00:00 2001
From: INADA Naoki <songofacandy@gmail.com>
Date: Tue, 18 Oct 2016 11:48:14 +0900
Subject: [PATCH] Issue #28452: Remove _asyncio._init_module function

---
 Lib/asyncio/futures.py   |  23 +++-----
 Modules/_asynciomodule.c | 121 ++++++++++++++++++---------------------
 2 files changed, 63 insertions(+), 81 deletions(-)

diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 87ae30aa09e..73215f50efe 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -431,21 +431,6 @@ def _copy_future_state(source, dest):
             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.
 
@@ -496,3 +481,11 @@ def wrap_future(future, *, loop=None):
     new_future = loop.create_future()
     _chain_future(future, new_future)
     return new_future
+
+
+try:
+    import _asyncio
+except ImportError:
+    pass
+else:
+    Future = _asyncio.Future
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index ce576e5799c..d1d9c5425ef 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -7,7 +7,6 @@ _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;
@@ -19,19 +18,6 @@ static PyObject *asyncio_CancelledError;
 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,
@@ -108,10 +94,6 @@ FutureObj_init(FutureObj *fut, PyObject *args, PyObject *kwds)
     PyObject *res = NULL;
     _Py_IDENTIFIER(get_debug);
 
-    if (_AsyncioMod_EnsureState()) {
-        return -1;
-    }
-
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$O", kwlist, &loop)) {
         return -1;
     }
@@ -218,10 +200,6 @@ PyDoc_STRVAR(pydoc_exception,
 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;
@@ -251,10 +229,6 @@ PyDoc_STRVAR(pydoc_set_result,
 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;
@@ -282,10 +256,6 @@ 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;
@@ -949,59 +919,75 @@ new_future_iter(PyObject *fut)
 
 /*********************** Module **************************/
 
-PyDoc_STRVAR(module_doc, "asyncio speedups.\n");
-
-PyObject *
-_init_module(PyObject *self, PyObject *args)
+static int
+init_module(void)
 {
-    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;
-    }
+    PyObject *module = NULL;
 
-    Py_INCREF(extract_stack);
-    Py_XSETREF(traceback_extract_stack, 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);
 
-    Py_INCREF(get_event_loop);
-    Py_XSETREF(asyncio_get_event_loop, 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);
 
-    Py_INCREF(repr_info_func);
-    Py_XSETREF(asyncio_repr_info_func, repr_info_func);
+    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(invalidStateError);
-    Py_XSETREF(asyncio_InvalidStateError, invalidStateError);
+    asyncio_InvalidStateError = PyObject_GetAttrString(module,
+                                                       "InvalidStateError");
+    if (asyncio_InvalidStateError == NULL) {
+        goto fail;
+    }
 
-    Py_INCREF(cancelledError);
-    Py_XSETREF(asyncio_CancelledError, cancelledError);
+    asyncio_CancelledError = PyObject_GetAttrString(module, "CancelledError");
+    if (asyncio_CancelledError == NULL) {
+        goto fail;
+    }
 
-    _asynciomod_ready = 1;
+    Py_DECREF(module);
+    return 0;
 
-    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 */
@@ -1012,6 +998,9 @@ static struct PyModuleDef _asynciomodule = {
 PyMODINIT_FUNC
 PyInit__asyncio(void)
 {
+    if (init_module() < 0) {
+        return NULL;
+    }
     if (PyType_Ready(&FutureType) < 0) {
         return NULL;
     }
-- 
2.30.9