[Python-Dev] PEP 492: async/await in Python; version 5 (original) (raw)

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