[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
-jJ
--
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