PEP 492 andPEP 525 introduce support for native coroutines andasynchronous generators usingasync /await syntax. This PEPproposes to add asynchronous versions of list, set, dict comprehensionsand generator expressions.
Python has extensive support for synchronous comprehensions, allowingto produce lists, dicts, and sets with a simple and concise syntax. Wepropose implementing similar syntactic constructions for theasynchronous code.
To illustrate the readability improvement, consider the followingexample:
result=[]asyncforiinaiter():ifi%2:result.append(i)
With the proposed asynchronous comprehensions syntax, the above codebecomes as short as:
result=[iasyncforiinaiter()ifi%2]
The PEP also makes it possible to use theawait expressions inall kinds of comprehensions:
result=[awaitfun()forfuninfuncs]
We propose to allow usingasyncfor inside list, set and dictcomprehensions. PendingPEP 525 approval, we can also allow creationof asynchronous generator expressions.
Examples:
{iasyncforiinagen()};[iasyncforiinagen()];{i:i**2asyncforiinagen()};(i**2asyncforiinagen()).It is allowed to useasyncfor along withif andforclauses in asynchronous comprehensions and generator expressions:
dataset={dataforlineinaiter()asyncfordatainlineifcheck(data)}
Asynchronous comprehensions are only allowed inside anasyncdeffunction.
In principle, asynchronous generator expressions are allowed inany context. However, in Python 3.6, due toasync andawaitsoft-keyword status, asynchronous generator expressions are onlyallowed in anasyncdef function. Onceasync andawaitbecome reserved keywords in Python 3.7, this restriction will beremoved.
await in ComprehensionsWe propose to allow the use ofawait expressions in bothasynchronous and synchronous comprehensions:
result=[awaitfun()forfuninfuncs]result={awaitfun()forfuninfuncs}result={fun:awaitfun()forfuninfuncs}result=[awaitfun()forfuninfuncsifawaitsmth]result={awaitfun()forfuninfuncsifawaitsmth}result={fun:awaitfun()forfuninfuncsifawaitsmth}result=[awaitfun()asyncforfuninfuncs]result={awaitfun()asyncforfuninfuncs}result={fun:awaitfun()asyncforfuninfuncs}result=[awaitfun()asyncforfuninfuncsifawaitsmth]result={awaitfun()asyncforfuninfuncsifawaitsmth}result={fun:awaitfun()asyncforfuninfuncsifawaitsmth}
This is only valid inasyncdef function body.
The proposal requires one change on the grammar level: adding theoptional “async” keyword tocomp_for:
comp_for:[ASYNC]'for'exprlist'in'or_test[comp_iter]
Thecomprehension AST node will have the newis_async argument.
The proposal is fully backwards compatible.
The implementation is tracked in issue 28008[3]. The referenceimplementation git repository is available at[2].
I thank Guido van Rossum, Victor Stinner and Elvis Pranskevichusfor their feedback, code reviews, and discussions around thisPEP.
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0530.rst
Last modified:2025-02-01 08:59:27 GMT