The parentheses can be omitted on calls with only one argument. See section
:ref:`calls` for details.
-Since Python 3.6, if the generator appears in an :keyword:`async def` function,
-then :keyword:`async for` clauses and :keyword:`await` expressions are permitted
-as with an asynchronous comprehension. If a generator expression
-contains either :keyword:`async for` clauses or :keyword:`await` expressions
-it is called an :dfn:`asynchronous generator expression`.
-An asynchronous generator expression yields a new asynchronous
-generator object, which is an asynchronous iterator
-(see :ref:`async-iterators`).
+If a generator expression contains either :keyword:`async for`
+clauses or :keyword:`await` expressions it is called an
+:dfn:`asynchronous generator expression`. An asynchronous generator
+expression returns a new asynchronous generator object,
+which is an asynchronous iterator (see :ref:`async-iterators`).
+
+.. versionchanged:: 3.7
+ Prior to Python 3.7, asynchronous generator expressions could
+ only appear in :keyword:`async def` coroutines. Starting
+ with 3.7, any function can use asynchronous generator expressions.
.. _yieldexpr:
t.cancel()
self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop))
+ def test_async_gen_expression_01(self):
+ async def arange(n):
+ for i in range(n):
+ await asyncio.sleep(0.01, loop=self.loop)
+ yield i
+
+ def make_arange(n):
+ # This syntax is legal starting with Python 3.7
+ return (i * 2 async for i in arange(n))
+
+ async def run():
+ return [i async for i in make_arange(10)]
+
+ res = self.loop.run_until_complete(run())
+ self.assertEqual(res, [i * 2 for i in range(10)])
+
+ def test_async_gen_expression_02(self):
+ async def wrap(n):
+ await asyncio.sleep(0.01, loop=self.loop)
+ return n
+
+ def make_arange(n):
+ # This syntax is legal starting with Python 3.7
+ return (i * 2 for i in range(n) if await wrap(i))
+
+ async def run():
+ return [i async for i in make_arange(10)]
+
+ res = self.loop.run_until_complete(run())
+ self.assertEqual(res, [i * 2 for i in range(1, 10)])
+
+
if __name__ == "__main__":
unittest.main()
[i async for i in els]
""",
+ """def bar():
+ {i: i async for i in els}
+ """,
+
+ """def bar():
+ {i async for i in els}
+ """,
+
"""def bar():
[await i for i in els]
""",
--- /dev/null
+Allow use of asynchronous generator expressions in synchronous functions.
is_async_generator = c->u->u_ste->ste_coroutine;
- if (is_async_generator && !is_async_function) {
+ if (is_async_generator && !is_async_function && type != COMP_GENEXP) {
if (e->lineno > c->u->u_lineno) {
c->u->u_lineno = e->lineno;
c->u->u_lineno_set = 0;