André Caron added the comment: > I believe you're not using the asyncio.task() function correctly.
I assume you meant asyncio.wait(). I just updated my gist with a variant of my example that uses the (done, pending) pair returned by asyncio.wait() as you suggested. The set of done futures that is returned does not help in this case because you need to test objects by set membership using something like "if f1 in done:", which will never be true because f1 is a coroutine object and the set contains a wrapper returned by asyncio.ensure_future(). So we're back to square 1. Because you cannot await multiple times on a coroutine object (in contrast to futures), you will need to explicitly call asyncio.ensure_future() on everything you pass to asyncio.wait() if you care about the future's result -- which is more often than not in my experience. > There are many reasons as to why we don't want coroutines to be awaitable many times. One of them is that we don't want low-level coroutine objects to hold references to return values. Coroutines in Python are exhaustible resources (like generators). I understand concerns for efficiency and management of scarce resources. However, I don't understand your comment. Maybe this has something to do with CPython/asyncio internals, which I know nothing about. If my code keeps a reference to the coroutine object, it can't be released right? I don't see how adding a reference to the return value or wrapping the coroutine object in a Task wrapper (in order to recover the return value) will affect the allocation of coroutine resources. > Well, coroutines are much more lower level than Future/Tasks. >From an implementer's point of view, maybe. From a user's point of vue, the >value of having an "awaitable" concept is that I can use different objects in >the same way. If the semantics of await expressions vary depending on the >awaitable's type, then the value of the abstraction is reduced. If we go back to the core of the issue, the real problem here is the fact that the current behaviour of multiple awaits on a coroutine object is surprising: nobody expects it to return None the 2nd time around. Raising a RuntimeError instead of returning None is still surprising behaviour IMO. In addition to that, the error message that was agreed upon in this issue suggests a programming error (you're not _supposed_ to await twice), but what I'm getting to here with my example is that asyncio.wait() is a common/legitimate use case of this. Anyways, if you insist on considering this a programming error, you should probably reject coroutine objects in calls to asyncio.wait() since there will be effectively no way of recovering the return value after the call to asyncio.wait(). ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25887> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com