Hi Guido, On 2015-04-22 11:50 AM, Guido van Rossum wrote: > On Wed, Apr 22, 2015 at 8:40 AM, Yury Selivanov <yselivanov.ml at gmail.com> > wrote: >> On the one hand I like your idea to disallow calling >> coroutines without a special keyword (await in case of >> PEP 492). It has downsides, but there is some >> elegance in it. On the other hand, I hate the idea >> of grammatically requiring parentheses for 'await' >> expressions. That feels non-pytonic to me. >> >> I'd be happy to hear others opinion on this topic. >> > I'm slowly warming up to Greg's notion that you can't call a coroutine (or > whatever it's called) without a special keyword. This makes a whole class > of bugs obvious the moment the code is executed. > > OTOH I'm still struggling with what you have to do to wrap a coroutine in a > Task, the way its done in asyncio by the Task() constructor, the > loop.create_task() method, and the async() function (perhaps to be renamed > to ensure_task() to make way for the async keyword). > If we apply Greg's ideas to PEP 492 we will have the following (Greg, correct me if I'm wrong): 1. '_typeobject' struct will get a new field 'tp_await'. We can reuse 'tp_reserved' for that probably. 2. We'll hack Gen(/ceval.c?) objects to raise an error if they are called directly and have a 'CO_COROUTINE' flag. 3. Task(), create_task() and async() will be modified to call 'coro.__await__(..)' if 'coro' has a 'CO_COROUTINE' flag. 4. 'await' will require parentheses grammatically. That will make it different from 'yield' expression. For instance, I still don't know what would 'await coro(123)()' mean. 5. 'await foo(*a, **k)' will be an equivalent to 'yield from type(coro).__await__(coro, *a, **k)' 6. If we ever decide to implement coroutine-generators -- async def functions with 'await' *and* some form of 'yield' -- we'll need to reverse the rule -- allow __call__ and disallow __await__ on such objects (so that you'll be able to write 'async for item in coro_gen()' instead of 'async for item in await coro_gen()'. To be honest, that's a lot of steps and hacks to make this concept work. I think that 'set_coroutine_wrapper()' solves all these problems while keeping the grammar and implementation simpler. Moreover, it allows to add some additional features to the wrapped coroutines, such as nicer repr() in debug mode (CoroWrapper in asyncio already does that) and other runtime checks. Thanks, Yury
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4