Introspection functions from the inspect module are designed for native types. Introspection functions from asyncio are designed for what asyncio treats as coroutines. Consider this example:
@asyncio.coroutine def coro(): print(‘hello’) ‘asyncio.iscoroutinefunction' will return ‘True' for ‘coro’, because it knows how specifically asyncio wraps non-generator functions. To make ‘inspect.iscoroutinefunction’ recognize ‘coro’ as a coroutine function we would need to make ‘inspect’ aware of asyncio. But asyncio is just one user of async/await and generator-based coroutines. Twisted and Tornado have their own coroutine decorators, we can’t make inspect to recognize coroutines from them all. Yury > On Nov 8, 2016, at 12:03 AM, Justin Mayfield <too...@gmail.com> wrote: > > I know this is documented in PEP 492 but I'm struggling to understand why the > inspect module has several test functions (iscoroutine, iscoroutinefunction, > isawaitable) that only work for native coros. Comparatively the same > functions in the asyncio module work for both native and generator based > coros. > > It was an interesting exercise for me to figure this out the hard way so it's > safe to say there is peril in this distinction for at least one developer. > Furthermore, the docs for both sets of functions don't elude to these subtle > but important distinctions. > > Are there good reasons for this distinction going forward? > > Here are some surprising (to me) tests... > > Python 3.5.2 (default, Oct 14 2016, 12:54:53) > [GCC 6.2.1 20160916 (Red Hat 6.2.1-2)] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import inspect > >>> import asyncio > >>> inspect.iscoroutinefunction(asyncio.sleep) > False > >>> asyncio.iscoroutinefunction(asyncio.sleep) > True > >>> inspect.iscoroutine(asyncio.sleep(1)) > False > >>> asyncio.iscoroutine(asyncio.sleep(1)) > True > >>> inspect.isawaitable(asyncio.sleep(1)) > 256 > > > The last test is particularly interesting; At least it's truthy? >