[Python-Dev] PEP 492: async/await in Python; version 5
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.
> 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.
More information about the Python-Dev