-
Notifications
You must be signed in to change notification settings - Fork 243
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
Document how to type hint for an async function used as a callback #424
Comments
I think you can use |
Yes, in general case it should be like this: async def bar(x: int) -> str:
return str(x)
cbar: Callable[[int], Awaitable[str]] = bar So that in your case it should probably be: async def foo(x: int): pass
callback: Callable[[int], Awaitable[None]] = foo Also note that without an explicit return annotation for What are the exact steps to get |
I've changed the title of this issue to make a documentation thing so that an example in the Callable docs and show how to do this. @ilevkivskyi As for triggering the error, if I type hint the callback as |
From a newbie's point of view, it seems like Coroutine was added as a short-hand way to declare this (eg #251) but I can't figure out how to use it in Python 3.6. Maybe I need 3.7. |
I don't think 3.7 makes a difference here, and you more likely want Awaitable instead of Coroutine. What issues are you running into? |
Maybe a better question is: is Coroutine documented somewhere with an example? I will use Callable[[int], Awaitable[None]] but I do not understand the generic Coroutine and it merely bugs me, nothing more. I can ignore it. Thank you. |
Not sure, but there are very few contexts where you'd actually need it. To declare an async callback, you would use |
I see the return value of an async function is now Coroutine instead of Awaitable. At any rate, this explains why Callable should be used instead of Coroutine. python/mypy@6519eb6 |
Callable[[int], Awaitable[None]] is as well satisfied by any def without async keyword which returns asyncio Future, Task or coroutine object. Type Coroutine specifies awaitables which support send() and throw() methods and the complete type is Coroutine[send_type, throw_type, return_type], each parameter is covariant. Coroutine[Any, Any, None] is the inferred type which is returned by your async def taking int and returning None when executed without await. Future/Task means you allow to schedule/execute tasks before a callback function starts or returns. Unlike when returning coroutine object which is scheduled at the code line where you await async def. If Future/Task should be disallowed then the type of the callback would have to be Callable[[int], Coroutine[Any, Any, None]]. It still supports plain def which returns coroutine object but it should not matter. And a closing note because of the similarity, Generator[send_type, throw_type, return_type] is an unrelated type to Coroutine[send_type, throw_type, return_type] hence they are not allowed as a callback nor async functions defined via @asyncio.coroutine annotation. Welcome to simplicity of typing:) |
I wonder if perhaps I'd love to write something simpler than async def startup():
...
app.add_middleware(MyThing, startup=startup)
class MyThing:
def __init__(self, app: ..., startup: Callable[[], Awaitable[None]]) Perhaps an alias, like |
There’s a proposal on typing-sig that would allow writing ‘async () -> None’ for that case. https://mail.python.org/archives/list/[email protected]/message/JZLYRAXJV34WAV5TKEOMA32V7ZLPOBFC/ |
Fixes python/typingGH-424 (cherry picked from commit 9588f88) Co-authored-by: Sam Bull <[email protected]>
Fixes python/typingGH-424 (cherry picked from commit 9588f88) Co-authored-by: Sam Bull <[email protected]>
Fixes python/typingGH-424 (cherry picked from commit 9588f88) Co-authored-by: Sam Bull <[email protected]>
Fixes python/typingGH-424 (cherry picked from commit 9588f88) Co-authored-by: Sam Bull <[email protected]>
Fixes python/typingGH-424 (cherry picked from commit 9588f88) Co-authored-by: Sam Bull <[email protected]>
I have (roughly) the following code:
The problem is I don't know what to type
callback
to. It isn't aCallable
as mypy says that "Function does not return a value" when I callawait callback(42)
. It isn't anAsyncIterable
,AsyncIterator
, or anAsyncGenerator
as it simply isn't. It isn't aCoroutine
as mypy says that they can't be called.So am I missing something on how to type this, or does there need to be an
AsyncCallable
added totyping
?The text was updated successfully, but these errors were encountered: