You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There seems to be no consensus in the codebase on how to handle Cython objects. Both inspect.iscoroutinefunction() and inspect.iscoroutine() are defined in the documentation for async def functions and their objects, respectively. Therefore, the following code should be valid for them:
This is because Cython uses its own objects for compiled functions and generators/coroutines/asynchronous generators. inspect.is<object>() returns True only for uncompiled objects, as it relies on the types module, but inspect.is<object>function() relies on checking function flags and handles function-like objects in a special way (for compatibility with Cython). As a result, we get the contradictory "coroutine function does not return a coroutine".
The problem is even deeper than one might imagine:
What if we want to define a universal decorator that works for both regular and asynchronous functions? We could use inspect.iscoroutinefunction(), but it has very limited detection (in particular, it cannot detect object with async def __call__()), and library developers will only be able to rely on inspect.markcoroutinefunction() after the Python 3.11's EOF. A frequently suggested alternative is to check the return value's type using inspect.isawaitable(), but this is actually shooting oneself in the foot, as it will lead to false positives for future-like objects (such as asyncio future objects, which are also awaitable). The most logical solution would be to use inspect.iscoroutine(), but it does not support Cython (and in fact, it is even less useful; see GrahamDumpleton/wrapt#236 (comment)).
It seems to me that the question of whether the standard library (and related tools) should be Cython-aware has not been fully explored, which leads to such contradictions. I marked the issue as a bug, since it violates the expected behavior for any consistent interpretation.
Bug report
Bug description:
There seems to be no consensus in the codebase on how to handle Cython objects. Both
inspect.iscoroutinefunction()andinspect.iscoroutine()are defined in the documentation forasync deffunctions and their objects, respectively. Therefore, the following code should be valid for them:The same semantics are also expected by typeshed, which defines annotations as follows (and thus declares support for introspection):
However, after
cythonize -i -3, the code changes its behavior:This is because Cython uses its own objects for compiled functions and generators/coroutines/asynchronous generators.
inspect.is<object>()returnsTrueonly for uncompiled objects, as it relies on the types module, butinspect.is<object>function()relies on checking function flags and handles function-like objects in a special way (for compatibility with Cython). As a result, we get the contradictory "coroutine function does not return a coroutine".The problem is even deeper than one might imagine:
inspect.get*state()does not work for compiled objects on Python ≥3.11 cython/cython#7448.types.GeneratorTypeto be used instead ofcollections.abc.Generatoras the return type of generator functions mypy#20522.collection.abc.FunctionABC for function-like objects #131983.What if we want to define a universal decorator that works for both regular and asynchronous functions? We could use
inspect.iscoroutinefunction(), but it has very limited detection (in particular, it cannot detect object withasync def __call__()), and library developers will only be able to rely oninspect.markcoroutinefunction()after the Python 3.11's EOF. A frequently suggested alternative is to check the return value's type usinginspect.isawaitable(), but this is actually shooting oneself in the foot, as it will lead to false positives for future-like objects (such as asyncio future objects, which are also awaitable). The most logical solution would be to useinspect.iscoroutine(), but it does not support Cython (and in fact, it is even less useful; see GrahamDumpleton/wrapt#236 (comment)).It seems to me that the question of whether the standard library (and related tools) should be Cython-aware has not been fully explored, which leads to such contradictions. I marked the issue as a bug, since it violates the expected behavior for any consistent interpretation.
CPython versions tested on:
3.9, 3.10, 3.11, 3.12, 3.13, 3.14
Operating systems tested on:
Linux