[Python-checkins] bpo-34755: Add few minor optimizations in _asynciomodule.c. (GH-9455)

Serhiy Storchaka webhook-mailer at python.org
Fri Sep 21 02:11:35 EDT 2018


https://github.com/python/cpython/commit/fb3e9c00ed79f4d880ab9a67aab861eb3660ec75
commit: fb3e9c00ed79f4d880ab9a67aab861eb3660ec75
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018-09-21T09:11:32+03:00
summary:

bpo-34755: Add few minor optimizations in _asynciomodule.c. (GH-9455)

files:
M Modules/_asynciomodule.c

diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 2ed033cacd85..fc91ebd854d0 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -10,6 +10,7 @@ module _asyncio
 
 /* identifiers used from some functions */
 _Py_IDENTIFIER(__asyncio_running_event_loop__);
+_Py_IDENTIFIER(_asyncio_future_blocking);
 _Py_IDENTIFIER(add_done_callback);
 _Py_IDENTIFIER(_all_tasks_compat);
 _Py_IDENTIFIER(call_soon);
@@ -22,7 +23,6 @@ _Py_IDENTIFIER(throw);
 
 /* State of the _asyncio module */
 static PyObject *asyncio_mod;
-static PyObject *inspect_isgenerator;
 static PyObject *traceback_extract_stack;
 static PyObject *asyncio_get_event_loop_policy;
 static PyObject *asyncio_future_repr_info_func;
@@ -1304,13 +1304,8 @@ FutureObj_repr(FutureObj *fut)
         return NULL;
     }
 
-    PyObject *rstr = NULL;
-    PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut),
-                                                 "__name__");
-    if (type_name != NULL) {
-        rstr = PyUnicode_FromFormat("<%S %U>", type_name, rinfo_s);
-        Py_DECREF(type_name);
-    }
+    PyObject *rstr = PyUnicode_FromFormat("<%s %U>",
+                                          _PyType_Name(Py_TYPE(fut)), rinfo_s);
     Py_DECREF(rinfo_s);
     return rstr;
 }
@@ -1326,7 +1321,6 @@ FutureObj_finalize(FutureObj *fut)
 
     PyObject *error_type, *error_value, *error_traceback;
     PyObject *context;
-    PyObject *type_name;
     PyObject *message = NULL;
     PyObject *func;
 
@@ -1344,14 +1338,8 @@ FutureObj_finalize(FutureObj *fut)
         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);
-    Py_DECREF(type_name);
+        "%s exception was never retrieved", _PyType_Name(Py_TYPE(fut)));
     if (message == NULL) {
         goto finally;
     }
@@ -1543,7 +1531,7 @@ static PyObject *
 FutureIter_send(futureiterobject *self, PyObject *unused)
 {
     /* Future.__iter__ doesn't care about values that are pushed to the
-     * generator, it just returns "self.result().
+     * generator, it just returns self.result().
      */
     return FutureIter_iternext(self);
 }
@@ -2702,163 +2690,142 @@ task_step_impl(TaskObj *task, PyObject *exc)
             goto different_loop;
         }
 
-        if (fut->fut_blocking) {
-            fut->fut_blocking = 0;
+        if (!fut->fut_blocking) {
+            goto yield_insteadof_yf;
+        }
 
-            /* result.add_done_callback(task._wakeup) */
-            wrapper = TaskWakeupMethWrapper_new(task);
-            if (wrapper == NULL) {
-                goto fail;
-            }
-            res = future_add_done_callback(
-                (FutureObj*)result, wrapper, task->task_context);
-            Py_DECREF(wrapper);
-            if (res == NULL) {
-                goto fail;
-            }
-            Py_DECREF(res);
+        fut->fut_blocking = 0;
 
-            /* task._fut_waiter = result */
-            task->task_fut_waiter = result;  /* no incref is necessary */
+        /* result.add_done_callback(task._wakeup) */
+        wrapper = TaskWakeupMethWrapper_new(task);
+        if (wrapper == NULL) {
+            goto fail;
+        }
+        res = future_add_done_callback(
+            (FutureObj*)result, wrapper, task->task_context);
+        Py_DECREF(wrapper);
+        if (res == NULL) {
+            goto fail;
+        }
+        Py_DECREF(res);
 
-            if (task->task_must_cancel) {
-                PyObject *r;
-                r = future_cancel(fut);
-                if (r == NULL) {
-                    return NULL;
-                }
-                if (r == Py_True) {
-                    task->task_must_cancel = 0;
-                }
-                Py_DECREF(r);
-            }
+        /* task._fut_waiter = result */
+        task->task_fut_waiter = result;  /* no incref is necessary */
 
-            Py_RETURN_NONE;
+        if (task->task_must_cancel) {
+            PyObject *r;
+            r = future_cancel(fut);
+            if (r == NULL) {
+                return NULL;
+            }
+            if (r == Py_True) {
+                task->task_must_cancel = 0;
+            }
+            Py_DECREF(r);
         }
-        else {
-            goto yield_insteadof_yf;
+
+        Py_RETURN_NONE;
+    }
+
+    /* Check if `result` is None */
+    if (result == Py_None) {
+        /* Bare yield relinquishes control for one event loop iteration. */
+        if (task_call_step_soon(task, NULL)) {
+            goto fail;
         }
+        return result;
     }
 
     /* Check if `result` is a Future-compatible object */
-    o = PyObject_GetAttrString(result, "_asyncio_future_blocking");
-    if (o == NULL) {
-        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
-            PyErr_Clear();
+    if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) {
+        goto fail;
+    }
+    if (o != NULL && o != Py_None) {
+        /* `result` is a Future-compatible object */
+        PyObject *wrapper;
+        PyObject *res;
+
+        int blocking = PyObject_IsTrue(o);
+        Py_DECREF(o);
+        if (blocking < 0) {
+            goto fail;
         }
-        else {
+
+        /* Check if `result` future is attached to a different loop */
+        PyObject *oloop = get_future_loop(result);
+        if (oloop == NULL) {
             goto fail;
         }
-    }
-    else {
-        if (o == Py_None) {
-            Py_DECREF(o);
+        if (oloop != task->task_loop) {
+            Py_DECREF(oloop);
+            goto different_loop;
         }
-        else {
-            /* `result` is a Future-compatible object */
-            PyObject *wrapper;
-            PyObject *res;
+        Py_DECREF(oloop);
 
-            int blocking = PyObject_IsTrue(o);
-            Py_DECREF(o);
-            if (blocking < 0) {
-                goto fail;
-            }
+        if (!blocking) {
+            goto yield_insteadof_yf;
+        }
 
-            /* Check if `result` future is attached to a different loop */
-            PyObject *oloop = get_future_loop(result);
-            if (oloop == NULL) {
-                goto fail;
-            }
-            if (oloop != task->task_loop) {
-                Py_DECREF(oloop);
-                goto different_loop;
-            }
-            else {
-                Py_DECREF(oloop);
-            }
+        /* result._asyncio_future_blocking = False */
+        if (_PyObject_SetAttrId(
+                result, &PyId__asyncio_future_blocking, Py_False) == -1) {
+            goto fail;
+        }
 
-            if (blocking) {
-                /* result._asyncio_future_blocking = False */
-                if (PyObject_SetAttrString(
-                        result, "_asyncio_future_blocking", Py_False) == -1) {
-                    goto fail;
-                }
+        wrapper = TaskWakeupMethWrapper_new(task);
+        if (wrapper == NULL) {
+            goto fail;
+        }
 
-                wrapper = TaskWakeupMethWrapper_new(task);
-                if (wrapper == NULL) {
-                    goto fail;
-                }
+        /* result.add_done_callback(task._wakeup) */
+        PyObject *add_cb = _PyObject_GetAttrId(
+            result, &PyId_add_done_callback);
+        if (add_cb == NULL) {
+            Py_DECREF(wrapper);
+            goto fail;
+        }
+        PyObject *stack[2];
+        stack[0] = wrapper;
+        stack[1] = (PyObject *)task->task_context;
+        res = _PyObject_FastCallKeywords(
+            add_cb, stack, 1, context_kwname);
+        Py_DECREF(add_cb);
+        Py_DECREF(wrapper);
+        if (res == NULL) {
+            goto fail;
+        }
+        Py_DECREF(res);
 
-                /* result.add_done_callback(task._wakeup) */
-                PyObject *add_cb = _PyObject_GetAttrId(
-                    result, &PyId_add_done_callback);
-                if (add_cb == NULL) {
-                    Py_DECREF(wrapper);
-                    goto fail;
-                }
-                PyObject *stack[2];
-                stack[0] = wrapper;
-                stack[1] = (PyObject *)task->task_context;
-                res = _PyObject_FastCallKeywords(
-                    add_cb, stack, 1, context_kwname);
-                Py_DECREF(add_cb);
-                Py_DECREF(wrapper);
-                if (res == NULL) {
-                    goto fail;
-                }
-                Py_DECREF(res);
-
-                /* task._fut_waiter = result */
-                task->task_fut_waiter = result;  /* no incref is necessary */
-
-                if (task->task_must_cancel) {
-                    PyObject *r;
-                    int is_true;
-                    r = _PyObject_CallMethodId(result, &PyId_cancel, NULL);
-                    if (r == NULL) {
-                        return NULL;
-                    }
-                    is_true = PyObject_IsTrue(r);
-                    Py_DECREF(r);
-                    if (is_true < 0) {
-                        return NULL;
-                    }
-                    else if (is_true) {
-                        task->task_must_cancel = 0;
-                    }
-                }
+        /* task._fut_waiter = result */
+        task->task_fut_waiter = result;  /* no incref is necessary */
 
-                Py_RETURN_NONE;
+        if (task->task_must_cancel) {
+            PyObject *r;
+            int is_true;
+            r = _PyObject_CallMethodId(result, &PyId_cancel, NULL);
+            if (r == NULL) {
+                return NULL;
             }
-            else {
-                goto yield_insteadof_yf;
+            is_true = PyObject_IsTrue(r);
+            Py_DECREF(r);
+            if (is_true < 0) {
+                return NULL;
+            }
+            else if (is_true) {
+                task->task_must_cancel = 0;
             }
         }
-    }
 
-    /* Check if `result` is None */
-    if (result == Py_None) {
-        /* Bare yield relinquishes control for one event loop iteration. */
-        if (task_call_step_soon(task, NULL)) {
-            goto fail;
-        }
-        return result;
+        Py_RETURN_NONE;
     }
 
+    Py_XDECREF(o);
     /* Check if `result` is a generator */
-    o = PyObject_CallFunctionObjArgs(inspect_isgenerator, result, NULL);
-    if (o == NULL) {
-        /* An exception in inspect.isgenerator */
+    res = PyObject_IsInstance(result, (PyObject*)&PyGen_Type);
+    if (res < 0) {
         goto fail;
     }
-    res = PyObject_IsTrue(o);
-    Py_DECREF(o);
-    if (res == -1) {
-        /* An exception while checking if 'val' is True */
-        goto fail;
-    }
-    if (res == 1) {
+    if (res) {
         /* `result` is a generator */
         o = task_set_error_soon(
             task, PyExc_RuntimeError,
@@ -2922,7 +2889,7 @@ task_step(TaskObj *task, PyObject *exc)
         return NULL;
     }
     else {
-        if(leave_task(task->task_loop, (PyObject*)task) < 0) {
+        if (leave_task(task->task_loop, (PyObject*)task) < 0) {
             Py_DECREF(res);
             return NULL;
         }
@@ -3237,7 +3204,6 @@ static void
 module_free(void *m)
 {
     Py_CLEAR(asyncio_mod);
-    Py_CLEAR(inspect_isgenerator);
     Py_CLEAR(traceback_extract_stack);
     Py_CLEAR(asyncio_future_repr_info_func);
     Py_CLEAR(asyncio_get_event_loop_policy);
@@ -3278,15 +3244,10 @@ module_init(void)
     }
 
 
-    context_kwname = PyTuple_New(1);
+    context_kwname = Py_BuildValue("(s)", "context");
     if (context_kwname == NULL) {
         goto fail;
     }
-    PyObject *context_str = PyUnicode_FromString("context");
-    if (context_str == NULL) {
-        goto fail;
-    }
-    PyTuple_SET_ITEM(context_kwname, 0, context_str);
 
 #define WITH_MOD(NAME) \
     Py_CLEAR(module); \
@@ -3319,9 +3280,6 @@ module_init(void)
     WITH_MOD("asyncio.coroutines")
     GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine")
 
-    WITH_MOD("inspect")
-    GET_MOD_ATTR(inspect_isgenerator, "isgenerator")
-
     WITH_MOD("traceback")
     GET_MOD_ATTR(traceback_extract_stack, "extract_stack")
 
@@ -3388,7 +3346,7 @@ PyInit__asyncio(void)
     if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) {
         return NULL;
     }
-    if(PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) {
+    if (PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) {
         return NULL;
     }
     if (PyType_Ready(&TaskType) < 0) {



More information about the Python-checkins mailing list