Repository navigation
asyncio.iscoroutinefunction(<async_generator>.asend) returns False #81371
Description
Activity
RaduMateiLcraru commented
on Jun 7, 2019 RaduMateiLcrarumannequinMannequinAuthorMore actionsasyncio.iscoroutinefunction(<async_generator>.__anext__) asyncio.iscoroutinefunction(<async_generator>.asend) asyncio.iscoroutinefunction(<async_generator>.athrow) asyncio.iscoroutinefunction(<async_generator>.aclose)
All of these return False, is this the intended behavior? Aren't all of these in fact coroutine functions?
- added3.7 (EOL)end of lifeend of lifetype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Jun 7, 2019 These functions are not coroutine functions but rather functions which return an awaitable object. You can use
inspect.isawaitableon the result ofasendto check if it is awaitable.@kumaraditya303 they are functions that return coroutines - otherwise they could not be used with
asyncio.create_task(agen.asend())>>> import asyncio >>> async def async_generator(): yield ... >>> asyncio.iscoroutine(async_generator().asend(None)) True >>>
so I think this needs re-opening
It is not a
coroutineobject but ratherasync_generator_asendobject which has methods and some attributes ofcoroutineso behaves like it.iscoroutinefunctiononly works correctly forasync deffunctions not native methods which returns anawaitableobject hence I suggested to useinspect.isawaitable.The bug here is with async_generator_asend/athrow
quoting @njsmith here:Conceptually the asend and athrow methods on async generators are just regular async functions, and if they were implemented that way they'd automatically raise the same "forgot to await" warnings that all async functions get. But because they're implemented directly in C, they don't get that infrastructure "for free"; it has to be added manually, and it's one of those minor fiddly details that's easy to miss when you're implementing something complicated like this.
now that
inspect.is*functionsupport duck-type functions it's possible for a built in function to implement all the needed features to pass the testCurrently async frameworks have specific hacks that require creating a prototypical async generator function and taking a copy of the built in asend/aclose types for inspection
now that inspect.is*function support duck-type functions it's possible for a built in function to implement all the needed features to pass the test Currently async frameworks have specific hacks that require creating a prototypical async generator function and taking a copy of the built in asend/aclose types for inspection
So how do you propose to fix this? Can you create a PR for this to discuss?
- added a commit that references this issue
on Feb 21, 2023 There is now a canonical way to mark a function that is not actually defined with
async defbut is known to return an awaitable, such thatinspect.iscoroutinefunctionwill returnTruefor it:inspect.markcoroutinefunction(see #99247)I think the mentioned methods of async generators should probably be marked in the same way, although that might be a bit tricky for methods implemented in C; it could involve some changes to the internal implementation details of
markcoroutinefunction.@kumaraditya303 Hi. Can you explain why aditional bifield in inderlying structures such as
PyCFunctionObjectisn't the way to fix this?This will never work properly because in native code we cannot distinguish between a function and a coroutine, regarding adding flags that's just going to complicate things. These aren't the only methods which return coroutine like objects, there can be more in third party code.
The proper way to workaround this is to use
inspect.isawaitableas I indicated above.I'm -1 on this, the users should use
inspect.isawaitablewhich works in all cases.
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs