File tree 2 files changed +30
-21
lines changed
2 files changed +30
-21
lines changed Original file line number Diff line number Diff line change 125
125
"ismodule" ,
126
126
"isroutine" ,
127
127
"istraceback" ,
128
+ "markcoroutinefunction" ,
128
129
"signature" ,
129
130
"stack" ,
130
131
"trace" ,
@@ -391,13 +392,22 @@ def isgeneratorfunction(obj):
391
392
See help(isfunction) for a list of attributes."""
392
393
return _has_code_flag (obj , CO_GENERATOR )
393
394
395
+ def markcoroutinefunction (func ):
396
+ """
397
+ Decorator to ensure callable is recognised as a coroutine function.
398
+ """
399
+ func .__code__ = func .__code__ .replace (
400
+ co_flags = func .__code__ .co_flags | CO_COROUTINE
401
+ )
402
+ return func
403
+
394
404
def iscoroutinefunction (obj ):
395
405
"""Return true if the object is a coroutine function.
396
406
397
407
Coroutine functions are defined with "async def" syntax.
398
408
"""
399
409
return _has_code_flag (obj , CO_COROUTINE ) or (
400
- callable (obj ) and _has_code_flag (obj .__call__ , CO_COROUTINE )
410
+ not isclass ( obj ) and callable (obj ) and _has_code_flag (obj .__call__ , CO_COROUTINE )
401
411
)
402
412
403
413
def isasyncgenfunction (obj ):
Original file line number Diff line number Diff line change @@ -202,30 +202,29 @@ def test_iscoroutine(self):
202
202
gen_coroutine_function_example ))))
203
203
self .assertTrue (inspect .isgenerator (gen_coro ))
204
204
205
- # Use subtest initially to see both failures.
206
- with self .subTest ("Wrapper not recognised." ):
207
- # First case: sync function returning an awaitable.
208
- async def _fn3 ():
209
- pass
205
+ async def _fn3 ():
206
+ pass
210
207
211
- def fn3 ():
212
- return _fn3 ()
208
+ @inspect .markcoroutinefunction
209
+ def fn3 ():
210
+ return _fn3 ()
213
211
214
- # TODO: Move this to decorator function.
215
- fn3 .__code__ = fn3 .__code__ .replace (
216
- co_flags = fn3 .__code__ .co_flags | inspect .CO_COROUTINE
217
- )
212
+ self .assertTrue (inspect .iscoroutinefunction (fn3 ))
218
213
219
- self .assertTrue (inspect .iscoroutinefunction (fn3 ))
214
+ class Cl :
215
+ async def __call__ (self ):
216
+ pass
217
+
218
+ self .assertFalse (inspect .iscoroutinefunction (Cl ))
219
+ self .assertTrue (inspect .iscoroutinefunction (Cl ()))
220
+
221
+ class Cl2 :
222
+ @inspect .markcoroutinefunction
223
+ def __call__ (self ):
224
+ pass
220
225
221
- with self .subTest ("Awaitable instance not recongnised." ):
222
- # Second case: a class with an async def __call__.
223
- # - instance is awaitable.
224
- class Cl :
225
- async def __call__ (self ):
226
- pass
227
- cl = Cl ()
228
- self .assertTrue (inspect .iscoroutinefunction (cl ))
226
+ self .assertFalse (inspect .iscoroutinefunction (Cl2 ))
227
+ self .assertTrue (inspect .iscoroutinefunction (Cl2 ()))
229
228
230
229
self .assertFalse (
231
230
inspect .iscoroutinefunction (unittest .mock .Mock ()))
You can’t perform that action at this time.
0 commit comments