I agree with Barry. We need more material that introduces the community to the new async/await syntax and the new concepts they bring. We borrowed the words from other languages but not all of their behaviours.
With coroutines in particular, we can do a better job of describing the differences between them and the previous generator-coroutines, the rules regarding what - if anything - is emitted from a '.send(<value>)', and how await resolves to a value. If you read through the asyncio Task code enough you'll figure it out, but we can't expect the community as a whole to learn the language, or asyncio, that way. Back to the OP's issue. The behaviour you are seeing of None being the value of an exhausted coroutine is consistent with that of an exhausted generator. Pushing the iterator with __next__() or .send() after completion results in a StopIteration being raised with a value of None regardless of what the final yielded/returned value was. Futures can be awaited multiple times because the __iter__/__await__ method defined causes them to raise StopIteration with the resolved value. I think the list is trying to tell you that awaiting a coro multiple times is simply not a valid case in Python because they are exhaustible resources. In asyncio, they are primarily a helpful mechanism for shipping promises to the Task wrapper. In virtually all cases the pattern is: > await some_async_def() and almost never: > coro = some_async_def() > await coro On Tue, Dec 15, 2015 at 9:34 PM Yury Selivanov <yselivanov...@gmail.com> wrote: > Roy, > > On 2015-12-15 8:29 PM, Roy Williams wrote: > [..] > > > > My proposal would be to automatically wrap the return value from an > > `async` function or any object implementing `__await__` in a future > > with `asyncio.ensure_future()`. This would allow async/await code to > > behave in a similar manner to other languages implementing async/await > > and would remain compatible with existing code using asyncio. > > > > What's your thoughts? > > Other languages, such as JavaScript, have a notion of event loop > integrated on a very deep level. In Python, there is no centralized > event loop, and asyncio is just one way of implementing one. > > In asyncio, Future objects are designed to inter-operate with an event > loop (that's also true for JS Promises), which means that in order to > automatically wrap Python coroutines in Futures, we'd have to define the > event loop deep in Python core. Otherwise it's impossible to implement > 'Future.add_done_callback', since there would be nothing that calls the > callbacks on completion. > > To avoid adding a built-in event loop, PEP 492 introduced coroutines as > an abstract language concept. David Beazley, for instance, doesn't like > Futures, and his new framework 'curio' does not have them at all. > > I highly doubt that we want to add a generalized event loop in Python > core, define a generalized Future interface, and make coroutines return > it. It's simply too much work with no clear wins. > > Now, your initial email highlights another problem: > > coro = coroutine() > print(await coro) # will print the result of coroutine > await coro # prints None > > This is a bug that needs to be fixed. We have two options: > > 1. Cache the result when the coroutine object is awaited first time. > Return the cached result when the coroutine object is awaited again. > > 2. Raise an error if the coroutine object is awaited more than once. > > The (1) option would solve your problem. But it also introduces new > complexity: the GC of result will be delayed; more importantly, some > users will wonder if we cache the result or run the coroutine again. > It's just not obvious. > > The (2) option is Pythonic and simple to understand/debug, IMHO. In > this case, the best way for you to solve your initial problem, would be > to have a decorator around your tasks. The decorator should wrap > coroutines with Futures (with asyncio.ensure_future) and everything will > work as you expect. > > Thanks, > Yury > > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > https://mail.python.org/mailman/options/python-dev/kevinjacobconway%40gmail.com >
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com