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

Yury Selivanov yselivanov.ml at gmail.com
Sat Apr 25 22:18:08 CEST 2015


Hi Guido,

On 2015-04-24 1:03 PM, Guido van Rossum wrote:
> *3. syntactic priority of `await`*
>
> Yury, could you tweak the syntax for `await` so that we can write the most
> common usages without parentheses? In particular I'd like to be able to
> write
> ```
> return await foo()
> with await foo() as bar: ...
> foo(await bar(), await bletch())
> ```
> (I don't care about `await foo() + await bar()` but it would be okay.)
> ```
> I think this is reasonable with some tweaks of the grammar (similar to what
> Greg did for cocall, but without requiring call syntax at the end).

I've done some experiments with grammar, and it looks like
we indeed can parse await quite differently from yield. Three
different options:


Option #1. Parse 'await' exactly like we parse 'yield'.
This how we parse 'await' in the latest version of reference
implementation.

Required grammar changes:
https://gist.github.com/1st1/cb0bd257b04adb87e167#file-option-1-patch

Repo to play with:
https://github.com/1st1/cpython/tree/await

Syntax:

   await a()
   res = (await a()) + (await b())
   res = (await (await a()))
   if (await a()): pass
   return (await a())
   print((await a()))
   func(arg=(await a()))
   await a() * b()


Option #2. Keep 'await_expr' in 'atom' terminal, but don't
require parentheses.

Required grammar changes:
https://gist.github.com/1st1/cb0bd257b04adb87e167#file-option-2-patch

Repo to play with (parser module is broken atm):
https://github.com/1st1/cpython/tree/await_noparens

Syntax:

   await a()
   res = (await a()) + await b() # w/o parens (a() + await b())
   res = await await a()
   if await a(): pass
   return await a()
   print(await a())
   func(arg=await a())
   await a() * b()


Option #3. Create a new terminal for await expression between
'atom' and 'power'.

Required grammar changes:
https://gist.github.com/1st1/cb0bd257b04adb87e167#file-option-3-patch

Repo to play with (parser module is broken atm):
https://github.com/1st1/cpython/tree/await_noparens2

Syntax:

   await a()
   res = await a() + await b()
   res = await (await a()) # invalid syntax w/o parens
   if await a(): pass
   return await a()
   print(await a())
   func(arg=await a())
   await (a() * b()) # w/o parens '(await a() * b())


I think that Option #3 is a clear winner.

Thanks,
Yury



More information about the Python-Dev mailing list