[Python-Dev] iscoroutinefunction vs. coroutines
Guido van Rossum
guido at python.org
Thu Mar 9 12:39:24 EST 2017
On Thu, Mar 9, 2017 at 3:04 AM, Matthias Urlichs <smurf at noris.de> wrote:
> Is this pattern
>
> def foo():
> return bar()
> async def bar():
> await <whatever>
>
> async def async_main():
> await foo()
>
> considered to be valid?
>
Yes, it is valid.
> The reason I'm asking is that some code out there likes to accept a
> might-be-a-coroutine-function argument, using
>
> def run_callback(fn):
> if iscoroutinefunction(fn):
> res = await fn()
> else:
> res = fn()
>
> instead of
>
> def run_callback(fn):
> res = fn()
> if iscoroutine(res):
> res = await res()
>
> The former obviously breaks when somebody combines these idioms and calls
>
> run_callback(foo)
>
> but I can't help but wonder whether the latter use might be deprecated, or
> even warned about, in the future and/or with non-CPython implementations.
>
In general I would recommend against patterns that support either
awaitables or non-awaitables. The recommended solution is for
run_callback() to require an awaitable, and if you have a function that
just returns the value, you should wrap it in an async def that doesn't use
await.
The difference between the two versions of run_callback() is merely the
difference you pointed out -- iscoroutinefunction(f) is not entirely
equivalent to iscoroutine(f()).
If you're thinking in terms of static types (e.g. PEP 484 and mypy), in the
latter version the type of `res` is problematic (it's Union[Awaitable[T],
T]), but there's an easy way to rewrite it to avoid that, while still
calling iscoroutine().
If there's something else you worry about with the latter please clarify.
But in general I would stay far away from this kind of "do what I mean" API
-- they are hard to reason about and difficult to debug.
--
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20170309/45bc374a/attachment.html>
More information about the Python-Dev
mailing list