Skip to content

asyncio.iscoroutinefunction(<async_generator>.asend) returns False #81371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
RaduMateiLcraru mannequin opened this issue Jun 7, 2019 · 10 comments
Closed

asyncio.iscoroutinefunction(<async_generator>.asend) returns False #81371

RaduMateiLcraru mannequin opened this issue Jun 7, 2019 · 10 comments
Labels
topic-asyncio type-bug An unexpected behavior, bug, or error

Comments

@RaduMateiLcraru
Copy link
Mannequin

RaduMateiLcraru mannequin commented Jun 7, 2019

BPO 37190
Nosy @asvetlov, @1st1

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:

assignee = None
closed_at = None
created_at = <Date 2019-06-07.08:57:50.425>
labels = ['type-bug', '3.7', 'expert-asyncio']
title = 'asyncio.iscoroutinefunction(<async_generator>.asend) returns False'
updated_at = <Date 2019-06-07.08:57:50.425>
user = 'https://bugs.python.org/RaduMateiLcraru'

bugs.python.org fields:

activity = <Date 2019-06-07.08:57:50.425>
actor = 'Radu Matei L\xc4\x83craru'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['asyncio']
creation = <Date 2019-06-07.08:57:50.425>
creator = 'Radu Matei L\xc4\x83craru'
dependencies = []
files = []
hgrepos = []
issue_num = 37190
keywords = []
message_count = 1.0
messages = ['344910']
nosy_count = 3.0
nosy_names = ['asvetlov', 'yselivanov', 'Radu Matei L\xc4\x83craru']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue37190'
versions = ['Python 3.6', 'Python 3.7']

Linked PRs

@RaduMateiLcraru
Copy link
Mannequin Author

RaduMateiLcraru mannequin commented Jun 7, 2019

asyncio.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?

@RaduMateiLcraru RaduMateiLcraru mannequin added 3.7 (EOL) end of life topic-asyncio type-bug An unexpected behavior, bug, or error labels Jun 7, 2019
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@ezio-melotti ezio-melotti moved this to Todo in asyncio Jul 17, 2022
@kumaraditya303
Copy link
Contributor

These functions are not coroutine functions but rather functions which return an awaitable object. You can use inspect.isawaitable on the result of asend to check if it is awaitable.

@kumaraditya303 kumaraditya303 closed this as not planned Won't fix, can't repro, duplicate, stale Jul 17, 2022
Repository owner moved this from Todo to Done in asyncio Jul 17, 2022
@graingert
Copy link
Contributor

graingert commented Jul 21, 2022

@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

@graingert graingert reopened this Jul 22, 2022
Repository owner moved this from Done to In Progress in asyncio Jul 22, 2022
@kumaraditya303
Copy link
Contributor

It is not a coroutine object but rather async_generator_asend object which has methods and some attributes of coroutine so behaves like it. iscoroutinefunction only works correctly for async def functions not native methods which returns an awaitable object hence I suggested to use inspect.isawaitable.

@kumaraditya303 kumaraditya303 removed the 3.7 (EOL) end of life label Jul 22, 2022
@graingert
Copy link
Contributor

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*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

@kumaraditya303
Copy link
Contributor

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?

@carljm
Copy link
Member

carljm commented Feb 22, 2023

There is now a canonical way to mark a function that is not actually defined with async def but is known to return an awaitable, such that inspect.iscoroutinefunction will return True for 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.

@wrongnull
Copy link
Contributor

@kumaraditya303 Hi. Can you explain why aditional bifield in inderlying structures such as PyCFunctionObject isn't the way to fix this?

@kumaraditya303
Copy link
Contributor

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.isawaitable as I indicated above.

@kumaraditya303
Copy link
Contributor

I'm -1 on this, the users should use inspect.isawaitable which works in all cases.

@kumaraditya303 kumaraditya303 closed this as not planned Won't fix, can't repro, duplicate, stale Aug 16, 2023
@github-project-automation github-project-automation bot moved this from Todo to Done in asyncio Aug 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-asyncio type-bug An unexpected behavior, bug, or error
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

4 participants