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
{{ message }}
Repository navigation
inspect.is*function() overloads do not match the runtime behavior #15293
TypeGuard-based overloads for inspect.is*function() were added in #8057, but they are somewhat controversial.
First, the first overload defines the return type via collections.abc.<Object>, while the rest define it via types.<Object>Type. As a result, type checkers infer the narrower type when the known return type differs from collections.abc.<Object>:
Second, inspect.is*function() also returns True for functions that return a non-native object (for example, if the function was compiled via Cython), which means that the return type may not be types.<Object>Type:
#!/usr/bin/env python3importinspectdefgenerator_function():
yieldasyncdefcoroutine_function():
passasyncdefasync_generator_function():
yielddefmain():
# `True` on both CPython and Cython:print(inspect.isgeneratorfunction(generator_function))
print(inspect.iscoroutinefunction(coroutine_function))
print(inspect.isasyncgenfunction(async_generator_function))
# `True` on CPython, `False` on Cython:print(inspect.isgenerator(generator_function()))
print(inspect.iscoroutine(coro:=coroutine_function()))
print(inspect.isasyncgen(async_generator_function()))
coro.close() # to avoid `RuntimeWarning`if__name__=="__main__":
main()
This is definitely not the expected behavior, which means that the first overload must remain. I think replacing types.<Object>Type with collections.abc.<Object> will suffice.
Hi, I'd like to work on this. I'll update the fallback overloads to use the corresponding collections.abc return protocols and add focused regression tests.
Activity
srittau commentedon Jan 23, 2026
Cc @AlexWaygood and @JelleZijlstra who were involved in the original PR.
JelleZijlstra commentedon Jan 23, 2026
Looking at the issues one by one:
x42005e1f commentedon Jan 23, 2026
I believe that the first overload has two purposes:
If we replace
CoroutineTypewithCoroutine, the output of my first example will look like this:But if we also remove the first overload, it will affect the first two cases:
This is definitely not the expected behavior, which means that the first overload must remain. I think replacing
types.<Object>Typewithcollections.abc.<Object>will suffice.refactor!: avoid native types
nightcityblade commentedon Aug 21, 2026
Hi, I'd like to work on this. I'll update the fallback overloads to use the corresponding collections.abc return protocols and add focused regression tests.