@@ -407,6 +407,64 @@ async def bar():
407407 with self .subTest (code = code ), self .assertRaises (SyntaxError ):
408408 compile (code , "<test>" , "exec" )
409409
410+ def test_async_comprehension_scope (self ):
411+ # List/set/dict comprehensions with await or async for are allowed
412+ # only in async functions, or at module level with top-level await.
413+ allowed = [
414+ "async def f():\n [await x for x in y]" ,
415+ "async def f():\n {await x for x in y}" ,
416+ "async def f():\n {k: await x for k, x in y}" ,
417+ "async def f():\n [x async for x in y]" ,
418+ "async def f():\n {x async for x in y}" ,
419+ "async def f():\n {k: x async for k, x in y}" ,
420+ "async def f():\n [[await x for x in y] for y in z]" ,
421+ ]
422+ for code in allowed :
423+ with self .subTest (code = code ):
424+ compile (code , "<test>" , "exec" )
425+
426+ # Generator expressions with await are async genexps and may appear
427+ # outside async functions.
428+ for code in [
429+ "(await x for x in y)" ,
430+ "def f():\n (await x for x in y)" ,
431+ "class C:\n (await x for x in y)" ,
432+ ]:
433+ with self .subTest (code = code ):
434+ compile (code , "<test>" , "exec" )
435+
436+ err = "asynchronous comprehension outside of an asynchronous function"
437+ invalid = [
438+ "[await x for x in y]" ,
439+ "{await x for x in y}" ,
440+ "{k: await x for k, x in y}" ,
441+ "[x async for x in y]" ,
442+ "{x async for x in y}" ,
443+ "{k: x async for k, x in y}" ,
444+ "[[await x for x in y] for y in z]" ,
445+ "[[x async for x in y] for y in z]" ,
446+ "def f():\n [await x for x in y]" ,
447+ "def f():\n [x async for x in y]" ,
448+ "async def f():\n def g():\n [await x for x in y]" ,
449+ "class C:\n [await x for x in y]" ,
450+ "class C:\n {await x for x in y}" ,
451+ "class C:\n {k: await x for k, x in y}" ,
452+ "class C:\n [x async for x in y]" ,
453+ "class C:\n [[await x for x in y] for y in z]" ,
454+ "async def f():\n class C:\n x = [await y for y in z]" ,
455+ "async def f():\n class C:\n x = [y async for y in z]" ,
456+ ]
457+ for code in invalid :
458+ with self .subTest (code = code ):
459+ support .check_syntax_error (self , code , err )
460+
461+ support .check_syntax_error (
462+ self , "await x" , "'await' outside function" )
463+ support .check_syntax_error (
464+ self , "class C:\n await x" , "'await' outside function" )
465+ support .check_syntax_error (
466+ self , "def f():\n await x" , "'await' outside async function" )
467+
410468 def test_badsyntax_2 (self ):
411469 samples = [
412470 """def foo():
0 commit comments