[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