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
Document how to type hint for an async function used as a callback #424
asyncdeffoo(x: int): passcallback=foo# What does this type to?
The problem is I don't know what to type callback to. It isn't a Callable as mypy says that "Function does not return a value" when I call await callback(42). It isn't an AsyncIterable, AsyncIterator, or an AsyncGenerator as it simply isn't. It isn't a Coroutine 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 to typing?
I think you can use Callable[[int], Awaitable[None]].
Reacted by jaredtkatz, kflu, Natalia Maniakowska, Tim Martin, ShagaleevAlexey, Nurettin Onur TUĞCU, Steven Pineda, Lucas, Etienne Landuré, PKlempe and 60 more
Also note that without an explicit return annotation for foo mypy infers Callable[[int], Awaitable[Any]], according to PEP 484 all missing annotations are treated as Any.
What are the exact steps to get Function does not return a value error? Are you using --strict-optional, a similar (spurious) error was reported recently in mypy, it can be quite misleading.
Reacted by nakajima, Radek Kyselý, kflu, Philippe Duval, Ivan Tung, Jerome Guibert, Maciej Wrześniewski, Aleksey Izmailov, Roberto Prevato, Nurettin Onur TUĞCU and 24 more
changed the title [-]type hint for an async function used as a callback[/-][+]Document how to type hint for an async function used as a callback[/+]on May 7, 2017
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.
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 Awaitable like in Ivan's and my messages further up in this thread.
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:)
Reacted by Sergey Nevmerzhitsky, Pragy Agarwal, McSinyx, Ellis Percival, Miriam Vellacott, Tushar Sadhwani, Kyle King, joegnis, Xiaofeng Lin, Dennis Skinner and 3 more
Reacted by Pragy Agarwal and Ellis Percival
Reacted by Dima Tisnek, Dev-Guy and Ilya Siamionau
Activity
JelleZijlstra commentedon May 7, 2017
I think you can use
Callable[[int], Awaitable[None]].ilevkivskyi commentedon May 7, 2017
Yes, in general case it should be like this:
So that in your case it should probably be:
Also note that without an explicit return annotation for
foomypy infersCallable[[int], Awaitable[Any]], according to PEP 484 all missing annotations are treated asAny.What are the exact steps to get
Function does not return a valueerror? Are you using--strict-optional, a similar (spurious) error was reported recently in mypy, it can be quite misleading.[-]type hint for an async function used as a callback[/-][+]Document how to type hint for an async function used as a callback[/+]brettcannon commentedon May 7, 2017
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
Callable[[Any], None]it causes that error message.terrisgit commentedon Jul 3, 2018
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.
JelleZijlstra commentedon Jul 3, 2018
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?
terrisgit commentedon Jul 3, 2018
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.
JelleZijlstra commentedon Jul 3, 2018
Not sure, but there are very few contexts where you'd actually need it. To declare an async callback, you would use
Awaitablelike in Ivan's and my messages further up in this thread.terrisgit commentedon Jul 5, 2018
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
vladap commentedon Oct 31, 2019
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:)
Add example for async functions.
dimaqq commentedon Nov 25, 2021
I wonder if perhaps
typinggot any simpler in the last 2~4 years?I'd love to write something simpler than
Callable[[], Awaitable[None]]for simple cases like this:Perhaps an alias, like
AsyncFunction[]orAsyncCallable[]would be easier on the eyes and newcomers?gvanrossum commentedon Nov 25, 2021
There’s a proposal on typing-sig that would allow writing ‘async () -> None’ for that case.
https://mail.python.org/archives/list/typing-sig@python.org/message/JZLYRAXJV34WAV5TKEOMA32V7ZLPOBFC/
typing docs: Add example for async functions (#20386)
typing docs: Add example for async functions (pythonGH-20386)
typing docs: Add example for async functions (GH-20386)
typing docs: Add example for async functions (GH-20386)
typing docs: Add example for async functions (pythonGH-20386)
typing docs: Add example for async functions (GH-20386)