[Python-Dev] PEP 492 vs. PEP 3152, new round

Victor Stinner victor.stinner at gmail.com
Fri Apr 24 23:32:20 CEST 2015


Hi,

2015-04-24 19:03 GMT+02:00 Guido van Rossum <guido at python.org>:
> 1. precise syntax of `async def`
>
> Of all the places to put `async` I still like *before* the `def` the best.

So do I.


> 2. do we need `async for` and `async with`
>
> Yes we do.

I agree.


> 3. syntactic priority of `await`
>
> Yury, could you tweak the syntax for `await` so that we can write the most
> common usages without parentheses?

IMO another point must be discussed, corner cases in the grammar and
parser of the current PEP & implementation:
https://www.python.org/dev/peps/pep-0492/#transition-period-shortcomings

And the fact the Python 3.7 will make async & await keywords without
proving a way to prepare the code for this major change in the Python
syntax.

According to the PEP, patching the parser to detect async & await as
keywords is almost a hack, and there are corner cases where it doesn't
work "as expected".

That's why I suggest to reconsider the idea of supporting an
*optional* "from __future__ import async" to get async and await as
keywords in the current file. This import would allow all crazy
syntax. The parser might suggest to use the import when it fails to
parse an async or await keyword :-)


If you don't like the compromise of a parser with corner cases and an
optional __future__ to "workaround these cases", I'm also ok to
reproduce what we did with the introduction of the with keyword. I
mean not supporting async nor await by default, and maing __future__
mandatory to get the new feature.

=> 0 risk of backward compatibility issue
=> no more crazy hacks in the parser


> 4. `cocall` vs. `await`
>
> The asyncio library is getting plenty of adoption and it has the concept of
> separating the *getting* of a future[1] from *waiting* for it.

My rationale in my other email was similar (ability to get a function
without calling it, as you wrote, like bounded methods), so obviously
I agree with it :-)

I accept the compromise of creating a coroutine object without wait
for it (obvious and common bug when learning asyncio). Hopefully, we
keep the coroutine wrapper feature (ok, maybe I suggested this idea to
Yury because I suffered so much when I learnt how to use asyncio ;-)),
so it will still be easy to emit a warning in debug mode.

On Stackoverflow, when someone posts a code with bug, I'm now replying
"please rerun your code with asyncio debug mode enabled" ;-) I also
mentionned it at the *beginning* of the asyncio doc (it's documented
at the end of the asyncio doc!).



> 5. do we really need `__aiter__` and friends
>
> There's a lot of added complexity, but I think it's worth it.

I agree. I don't see how to keep the PEP consistent without having new
dedicated protocols.


> 6. StopAsyncException

(Sorry, I have no opinion on this point.)


> 7. compatibility with asyncio and existing users of it

The current state of the PEP makes types.coroutine() mandatory. If a
generator-based coroutine is not modified with types.coroutine, await
cannot be used on it. To be more concrete: asyncio coroutines not
declared with @asyncio.coroutine cannot be used with await.

Would it be crazy to allow waiting on a generator-based coroutine
(current asyncio coroutines) without having to call types.coroutine()
on it?

Maybe I just missed the purpose of disallow this.

It's also possible to modify asyncio to detect at runtime when an
asyncio coroutine is not decorated by @asyncio.coroutine (emit a
warning or even raise an exception).

Victor


More information about the Python-Dev mailing list