@@ -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 */
2425static PyObject * asyncio_mod ;
25- static PyObject * inspect_isgenerator ;
2626static PyObject * traceback_extract_stack ;
2727static PyObject * asyncio_get_event_loop_policy ;
2828static 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 *
15431531FutureIter_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
32373204module_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