How can I find out if a function or method is a normal function or an async function? I would like my code to automatically support normal or async callbacks and need a way
Co-routines have the COROUTINE flag set, bit 7 in the code flags:
>>> async def foo(): pass
>>> foo.__code__.co_flags & (1 << 7)
128 # not 0, so the flag is set.
The value 128 is stored as a constant in the inspect module:
>>> import inspect
>>> inspect.CO_COROUTINE
128
>>> foo.__code__.co_flags & inspect.CO_COROUTINE
128
The inspect.iscoroutinefunction() function does just that; test if the object is a function or method (to ensure there is a __code__ attribute) and test for that flag. See the source code.
Of course, using inspect.iscoroutinefunction() is the most readable and guaranteed to continue to work if ever the code flags were to change:
>>> inspect.iscoroutinefunction(foo)
True