Ben Darnell added the comment: On Tue, Jun 9, 2015 at 10:12 PM, Yury Selivanov <rep...@bugs.python.org> wrote:
> > Yury Selivanov added the comment: > > > All this checking for coroutine-ness feels very strange to me. It's > anti-duck-typing: [..] > > Why is it "anti-duck-typing"? Awaitable is an object that implements > __await__. With this patch coroutines are a separate type with __await__ > (although, ceval doesn't use it to make things faster). > Anti-duck-typing isn't quite the right word. What I meant was that Python 3.4 had generators that were used as coroutines. When we introduced __await__ in 3.5, we could have added __await__ as a method for all generators, since all generators have the necessary send/throw/close methods. But we didn't, and now we require an explicit marker that a given object was intended for a particular use instead of inferring that intention from the set of methods available. > > In asyncio we check for "coroutine-ness" only to raise errors if someone > passes a wrong object, or to make @asyncio.coroutine work (which will go > away eventually). > The check for coroutine-ness is not just in asyncio; it happens in the core interpreter. Tornado has to adapt to this check in order to interoperate with 'async def' coroutines. > > > Now, not only must it return a generator with the special coroutine > flag, the callable itself must be of the right type [..] > > Not sure what you mean here. It doesn't matter what callable is. It only > matters if it returns a native coroutine, a generator-based coroutine, or > an object with "__await__". > The type of the callable matters for the types.coroutine decorator. In order to get a coroutine object instead of a generator object, I must apply types.coroutine to the actual underlying generator, and not any wrapper. > > > Attempting to divide generators into awaitable and non-awaitable subsets > is a complex solution to a problem that I'm not convinced is real. > > Well, 'await' expression is a new operator, and it makes total sense to > limit its usage only to awaitables. Awaiting on a generator that yields a > fibonacci sequence just doesn't make any sense, and *is* error prone. I > think it would be a major mistake to allow this just to make things a > little bit more convenient during the transition period. > > This particular patch does not divide generators in awaitables and > non-awaitables, it introduces a new type for 'async def' coroutines. All > confusion with old generator-based coroutines and @coroutine decorator is > here only because we try to be backwards compatible; the compatibility > layer can be removed in 3.7 or 3.8. > There are three eras of coroutines to consider: 'async def' in 3.5+, 'yield from' in 3.3-3.4, and 'yield' in 2.5+. I'm trying to provide a path from 'yield' to 'async def'; this compatibility layer will remain relevant as long as people are migrating from 2.7. > > > Was there a problem in practice with Python 3.4's asyncio in which > people used "yield from" in a coroutine with generators that were intended > to be iterators instead? > > Yes, a lot of people were confused where they have coroutines and where > they have generators, and this was even mentioned in the Rationale section > of the PEP. > I understand that yield-based coroutines can be confusing, but is this particular kind of confusion bad enough that if someone writes 'await fibonacci_generator()' we have to raise "TypeError: object generator can't be used in 'await' expression" instead of "RuntimeError: Task got bad yield: 1"? (that error message from asyncio could definitely be improved, but the fact that no one has improved it suggests that the problem isn't that severe) My goal here is to make it possible for Tornado applications running on 3.5 to use 'async def' and 'await' even though Tornado itself must remain compatible with 2.7 (as do many of the libraries that make up the Tornado ecosystem; I don't want libraries to have to update for compatibility with this feature). This is doable (I think) but non-trivial in the current design; making all generators awaitable would make it easier. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue24400> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com