[Python-Dev] PEP 492: async/await in Python; version 5

Jim J. Jewett jimjjewett at gmail.com
Tue May 5 21:40:01 CEST 2015

On Tue May 5 18:29:44 CEST 2015, Yury Selivanov posted an updated PEP492.

Where are the following over-simplifications wrong?

(1)  The PEP is intended for use (almost exclusively) with
asychronous IO and a scheduler such as the asynchio event loop.

(2)  The new syntax is intended to make it easier to recognize when
a task's execution may be interrupted by arbitrary other tasks, and
the interrupted task therefore has to revalidate assumptions about
shared data.

With threads, CPython can always suspend a task between op-codes,
but with a sufficiently comprehensive loop (and sufficiently
coooperative tasks), tasks *should* only be suspended when they
make an explicit request to *wait* for an answer, and these points
*should* be marked syntactically.

(3)  The new constructs explicitly do NOT support any sort of
concurrent execution within a task; they are for use precisely
when otherwise parallel subtasks are being linearized by pausing
and waiting for the results.

Over-simplifications 4-6 assume a world with standardized futures
based on concurrent.futures, where .result either returns the
result or raises the exception (or raises another exception about
timeout or cancellation).

[Note that the actual PEP uses iteration over the results of a new
__await__ magic method, rather than .result on the object itself.
I couldn't tell whether this was for explicit marking, or just for
efficiency in avoiding future creation.]

(4)  "await EXPR" is just syntactic sugar for EXPR.result

except that, by being syntax, it better marks locations where
unrelated tasks might have a chance to change shared data.

[And that, as currently planned, the result of an await isn't
actually the result; it is an iterator of results.]

(5)  "async def" is just syntactic sugar for "def", 

except that, by being syntax, it better marks the signatures of
functions and methods where unrelated tasks might have a chance
to change shared data after execution has already begun.

(5A) As the PEP currently stands, it is also a promise that the
function will NOT produce a generator used as an iterator; if a
generator-iterator needs to wait for something else at some point,
that will need to be done differently.

I derive this limitation from
   "It is a ``SyntaxError`` to have ``yield`` or ``yield from``
    expressions in an ``async`` function."

but I don't understand how this limitation works with things like a
per-line file iterator that might need to wait for the file to
be initially opened.

(6)  async with EXPR as VAR:

would be equivalent to:

    with EXPR as VAR:

except that
  __enter__() would be replaced by next(await __enter__()) # __enter__().result
  __exit__() would be replaced by  next(await __exit__())  # __exit__().result

(7)  async for elem in iter:

would be shorthand for:

    for elem in iter:
        elem = next(await elem) # elem.result



If there are still threading problems with my replies, please
email me with details, so that I can try to resolve them.  -jJ

More information about the Python-Dev mailing list