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

Yury Selivanov yselivanov.ml at gmail.com
Tue May 5 22:00:36 CEST 2015



On 2015-05-05 3:40 PM, Jim J. Jewett wrote:
> 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.

Yes. You can also use it for UI loops.  Basically, anything
that can call your code asynchronously.

>
> (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.

Yes.
>
>
> 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.]

I'm not sure how to comment on (4).  Perhaps I don't
understand some notation that you're using.  If anything,
it's more of a syntactic sugar for 'yield from EXPR'.

>
> (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.

It also sets "CO_COROUTINE | CO_GENERATOR" flags, that
are very important.

>
> (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.

Per-line file iterator can be implemented with __aiter__,
__anext__ protocol.  __aiter__ is a coroutine, you can
open/start reading your file there.

>
> (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

I'm not sure I understand what you mean by
"next(await EXPR)" notation.


Yury


More information about the Python-Dev mailing list