Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fb3e9c0

Browse files
bpo-34755: Add few minor optimizations in _asynciomodule.c. (GH-9455)
1 parent 91e6c87 commit fb3e9c0

1 file changed

Lines changed: 116 additions & 158 deletions

File tree

Modules/_asynciomodule.c

Lines changed: 116 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module _asyncio
1010

1111
/* identifiers used from some functions */
1212
_Py_IDENTIFIER(__asyncio_running_event_loop__);
13+
_Py_IDENTIFIER(_asyncio_future_blocking);
1314
_Py_IDENTIFIER(add_done_callback);
1415
_Py_IDENTIFIER(_all_tasks_compat);
1516
_Py_IDENTIFIER(call_soon);
@@ -22,7 +23,6 @@ _Py_IDENTIFIER(throw);
2223

2324
/* State of the _asyncio module */
2425
static PyObject *asyncio_mod;
25-
static PyObject *inspect_isgenerator;
2626
static PyObject *traceback_extract_stack;
2727
static PyObject *asyncio_get_event_loop_policy;
2828
static PyObject *asyncio_future_repr_info_func;
@@ -1304,13 +1304,8 @@ FutureObj_repr(FutureObj *fut)
13041304
return NULL;
13051305
}
13061306

1307-
PyObject *rstr = NULL;
1308-
PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut),
1309-
"__name__");
1310-
if (type_name != NULL) {
1311-
rstr = PyUnicode_FromFormat("<%S %U>", type_name, rinfo_s);
1312-
Py_DECREF(type_name);
1313-
}
1307+
PyObject *rstr = PyUnicode_FromFormat("<%s %U>",
1308+
_PyType_Name(Py_TYPE(fut)), rinfo_s);
13141309
Py_DECREF(rinfo_s);
13151310
return rstr;
13161311
}
@@ -1326,7 +1321,6 @@ FutureObj_finalize(FutureObj *fut)
13261321

13271322
PyObject *error_type, *error_value, *error_traceback;
13281323
PyObject *context;
1329-
PyObject *type_name;
13301324
PyObject *message = NULL;
13311325
PyObject *func;
13321326

@@ -1344,14 +1338,8 @@ FutureObj_finalize(FutureObj *fut)
13441338
goto finally;
13451339
}
13461340

1347-
type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), "__name__");
1348-
if (type_name == NULL) {
1349-
goto finally;
1350-
}
1351-
13521341
message = PyUnicode_FromFormat(
1353-
"%S exception was never retrieved", type_name);
1354-
Py_DECREF(type_name);
1342+
"%s exception was never retrieved", _PyType_Name(Py_TYPE(fut)));
13551343
if (message == NULL) {
13561344
goto finally;
13571345
}
@@ -1543,7 +1531,7 @@ static PyObject *
15431531
FutureIter_send(futureiterobject *self, PyObject *unused)
15441532
{
15451533
/* Future.__iter__ doesn't care about values that are pushed to the
1546-
* generator, it just returns "self.result().
1534+
* generator, it just returns self.result().
15471535
*/
15481536
return FutureIter_iternext(self);
15491537
}
@@ -2702,163 +2690,142 @@ task_step_impl(TaskObj *task, PyObject *exc)
27022690
goto different_loop;
27032691
}
27042692

2705-
if (fut->fut_blocking) {
2706-
fut->fut_blocking = 0;
2693+
if (!fut->fut_blocking) {
2694+
goto yield_insteadof_yf;
2695+
}
27072696

2708-
/* result.add_done_callback(task._wakeup) */
2709-
wrapper = TaskWakeupMethWrapper_new(task);
2710-
if (wrapper == NULL) {
2711-
goto fail;
2712-
}
2713-
res = future_add_done_callback(
2714-
(FutureObj*)result, wrapper, task->task_context);
2715-
Py_DECREF(wrapper);
2716-
if (res == NULL) {
2717-
goto fail;
2718-
}
2719-
Py_DECREF(res);
2697+
fut->fut_blocking = 0;
27202698

2721-
/* task._fut_waiter = result */
2722-
task->task_fut_waiter = result; /* no incref is necessary */
2699+
/* result.add_done_callback(task._wakeup) */
2700+
wrapper = TaskWakeupMethWrapper_new(task);
2701+
if (wrapper == NULL) {
2702+
goto fail;
2703+
}
2704+
res = future_add_done_callback(
2705+
(FutureObj*)result, wrapper, task->task_context);
2706+
Py_DECREF(wrapper);
2707+
if (res == NULL) {
2708+
goto fail;
2709+
}
2710+
Py_DECREF(res);
27232711

2724-
if (task->task_must_cancel) {
2725-
PyObject *r;
2726-
r = future_cancel(fut);
2727-
if (r == NULL) {
2728-
return NULL;
2729-
}
2730-
if (r == Py_True) {
2731-
task->task_must_cancel = 0;
2732-
}
2733-
Py_DECREF(r);
2734-
}
2712+
/* task._fut_waiter = result */
2713+
task->task_fut_waiter = result; /* no incref is necessary */
27352714

2736-
Py_RETURN_NONE;
2715+
if (task->task_must_cancel) {
2716+
PyObject *r;
2717+
r = future_cancel(fut);
2718+
if (r == NULL) {
2719+
return NULL;
2720+
}
2721+
if (r == Py_True) {
2722+
task->task_must_cancel = 0;
2723+
}
2724+
Py_DECREF(r);
27372725
}
2738-
else {
2739-
goto yield_insteadof_yf;
2726+
2727+
Py_RETURN_NONE;
2728+
}
2729+
2730+
/* Check if `result` is None */
2731+
if (result == Py_None) {
2732+
/* Bare yield relinquishes control for one event loop iteration. */
2733+
if (task_call_step_soon(task, NULL)) {
2734+
goto fail;
27402735
}
2736+
return result;
27412737
}
27422738

27432739
/* Check if `result` is a Future-compatible object */
2744-
o = PyObject_GetAttrString(result, "_asyncio_future_blocking");
2745-
if (o == NULL) {
2746-
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2747-
PyErr_Clear();
2740+
if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) {
2741+
goto fail;
2742+
}
2743+
if (o != NULL && o != Py_None) {
2744+
/* `result` is a Future-compatible object */
2745+
PyObject *wrapper;
2746+
PyObject *res;
2747+
2748+
int blocking = PyObject_IsTrue(o);
2749+
Py_DECREF(o);
2750+
if (blocking < 0) {
2751+
goto fail;
27482752
}
2749-
else {
2753+
2754+
/* Check if `result` future is attached to a different loop */
2755+
PyObject *oloop = get_future_loop(result);
2756+
if (oloop == NULL) {
27502757
goto fail;
27512758
}
2752-
}
2753-
else {
2754-
if (o == Py_None) {
2755-
Py_DECREF(o);
2759+
if (oloop != task->task_loop) {
2760+
Py_DECREF(oloop);
2761+
goto different_loop;
27562762
}
2757-
else {
2758-
/* `result` is a Future-compatible object */
2759-
PyObject *wrapper;
2760-
PyObject *res;
2763+
Py_DECREF(oloop);
27612764

2762-
int blocking = PyObject_IsTrue(o);
2763-
Py_DECREF(o);
2764-
if (blocking < 0) {
2765-
goto fail;
2766-
}
2765+
if (!blocking) {
2766+
goto yield_insteadof_yf;
2767+
}
27672768

2768-
/* Check if `result` future is attached to a different loop */
2769-
PyObject *oloop = get_future_loop(result);
2770-
if (oloop == NULL) {
2771-
goto fail;
2772-
}
2773-
if (oloop != task->task_loop) {
2774-
Py_DECREF(oloop);
2775-
goto different_loop;
2776-
}
2777-
else {
2778-
Py_DECREF(oloop);
2779-
}
2769+
/* result._asyncio_future_blocking = False */
2770+
if (_PyObject_SetAttrId(
2771+
result, &PyId__asyncio_future_blocking, Py_False) == -1) {
2772+
goto fail;
2773+
}
27802774

2781-
if (blocking) {
2782-
/* result._asyncio_future_blocking = False */
2783-
if (PyObject_SetAttrString(
2784-
result, "_asyncio_future_blocking", Py_False) == -1) {
2785-
goto fail;
2786-
}
2775+
wrapper = TaskWakeupMethWrapper_new(task);
2776+
if (wrapper == NULL) {
2777+
goto fail;
2778+
}
27872779

2788-
wrapper = TaskWakeupMethWrapper_new(task);
2789-
if (wrapper == NULL) {
2790-
goto fail;
2791-
}
2780+
/* result.add_done_callback(task._wakeup) */
2781+
PyObject *add_cb = _PyObject_GetAttrId(
2782+
result, &PyId_add_done_callback);
2783+
if (add_cb == NULL) {
2784+
Py_DECREF(wrapper);
2785+
goto fail;
2786+
}
2787+
PyObject *stack[2];
2788+
stack[0] = wrapper;
2789+
stack[1] = (PyObject *)task->task_context;
2790+
res = _PyObject_FastCallKeywords(
2791+
add_cb, stack, 1, context_kwname);
2792+
Py_DECREF(add_cb);
2793+
Py_DECREF(wrapper);
2794+
if (res == NULL) {
2795+
goto fail;
2796+
}
2797+
Py_DECREF(res);
27922798

2793-
/* result.add_done_callback(task._wakeup) */
2794-
PyObject *add_cb = _PyObject_GetAttrId(
2795-
result, &PyId_add_done_callback);
2796-
if (add_cb == NULL) {
2797-
Py_DECREF(wrapper);
2798-
goto fail;
2799-
}
2800-
PyObject *stack[2];
2801-
stack[0] = wrapper;
2802-
stack[1] = (PyObject *)task->task_context;
2803-
res = _PyObject_FastCallKeywords(
2804-
add_cb, stack, 1, context_kwname);
2805-
Py_DECREF(add_cb);
2806-
Py_DECREF(wrapper);
2807-
if (res == NULL) {
2808-
goto fail;
2809-
}
2810-
Py_DECREF(res);
2811-
2812-
/* task._fut_waiter = result */
2813-
task->task_fut_waiter = result; /* no incref is necessary */
2814-
2815-
if (task->task_must_cancel) {
2816-
PyObject *r;
2817-
int is_true;
2818-
r = _PyObject_CallMethodId(result, &PyId_cancel, NULL);
2819-
if (r == NULL) {
2820-
return NULL;
2821-
}
2822-
is_true = PyObject_IsTrue(r);
2823-
Py_DECREF(r);
2824-
if (is_true < 0) {
2825-
return NULL;
2826-
}
2827-
else if (is_true) {
2828-
task->task_must_cancel = 0;
2829-
}
2830-
}
2799+
/* task._fut_waiter = result */
2800+
task->task_fut_waiter = result; /* no incref is necessary */
28312801

2832-
Py_RETURN_NONE;
2802+
if (task->task_must_cancel) {
2803+
PyObject *r;
2804+
int is_true;
2805+
r = _PyObject_CallMethodId(result, &PyId_cancel, NULL);
2806+
if (r == NULL) {
2807+
return NULL;
28332808
}
2834-
else {
2835-
goto yield_insteadof_yf;
2809+
is_true = PyObject_IsTrue(r);
2810+
Py_DECREF(r);
2811+
if (is_true < 0) {
2812+
return NULL;
2813+
}
2814+
else if (is_true) {
2815+
task->task_must_cancel = 0;
28362816
}
28372817
}
2838-
}
28392818

2840-
/* Check if `result` is None */
2841-
if (result == Py_None) {
2842-
/* Bare yield relinquishes control for one event loop iteration. */
2843-
if (task_call_step_soon(task, NULL)) {
2844-
goto fail;
2845-
}
2846-
return result;
2819+
Py_RETURN_NONE;
28472820
}
28482821

2822+
Py_XDECREF(o);
28492823
/* Check if `result` is a generator */
2850-
o = PyObject_CallFunctionObjArgs(inspect_isgenerator, result, NULL);
2851-
if (o == NULL) {
2852-
/* An exception in inspect.isgenerator */
2824+
res = PyObject_IsInstance(result, (PyObject*)&PyGen_Type);
2825+
if (res < 0) {
28532826
goto fail;
28542827
}
2855-
res = PyObject_IsTrue(o);
2856-
Py_DECREF(o);
2857-
if (res == -1) {
2858-
/* An exception while checking if 'val' is True */
2859-
goto fail;
2860-
}
2861-
if (res == 1) {
2828+
if (res) {
28622829
/* `result` is a generator */
28632830
o = task_set_error_soon(
28642831
task, PyExc_RuntimeError,
@@ -2922,7 +2889,7 @@ task_step(TaskObj *task, PyObject *exc)
29222889
return NULL;
29232890
}
29242891
else {
2925-
if(leave_task(task->task_loop, (PyObject*)task) < 0) {
2892+
if (leave_task(task->task_loop, (PyObject*)task) < 0) {
29262893
Py_DECREF(res);
29272894
return NULL;
29282895
}
@@ -3237,7 +3204,6 @@ static void
32373204
module_free(void *m)
32383205
{
32393206
Py_CLEAR(asyncio_mod);
3240-
Py_CLEAR(inspect_isgenerator);
32413207
Py_CLEAR(traceback_extract_stack);
32423208
Py_CLEAR(asyncio_future_repr_info_func);
32433209
Py_CLEAR(asyncio_get_event_loop_policy);
@@ -3278,15 +3244,10 @@ module_init(void)
32783244
}
32793245

32803246

3281-
context_kwname = PyTuple_New(1);
3247+
context_kwname = Py_BuildValue("(s)", "context");
32823248
if (context_kwname == NULL) {
32833249
goto fail;
32843250
}
3285-
PyObject *context_str = PyUnicode_FromString("context");
3286-
if (context_str == NULL) {
3287-
goto fail;
3288-
}
3289-
PyTuple_SET_ITEM(context_kwname, 0, context_str);
32903251

32913252
#define WITH_MOD(NAME) \
32923253
Py_CLEAR(module); \
@@ -3319,9 +3280,6 @@ module_init(void)
33193280
WITH_MOD("asyncio.coroutines")
33203281
GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine")
33213282

3322-
WITH_MOD("inspect")
3323-
GET_MOD_ATTR(inspect_isgenerator, "isgenerator")
3324-
33253283
WITH_MOD("traceback")
33263284
GET_MOD_ATTR(traceback_extract_stack, "extract_stack")
33273285

@@ -3388,7 +3346,7 @@ PyInit__asyncio(void)
33883346
if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) {
33893347
return NULL;
33903348
}
3391-
if(PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) {
3349+
if (PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) {
33923350
return NULL;
33933351
}
33943352
if (PyType_Ready(&TaskType) < 0) {

0 commit comments

Comments
 (0)