@@ -12,6 +12,10 @@ async def foo() -> Any:
1212 await foo ()
1313
1414
15+ def bar (* args ) -> Any :
16+ ...
17+
18+
1519async def foo_yield_1 ():
1620 await foo ()
1721 yield 5
@@ -886,3 +890,97 @@ async def foo_test():
886890@pytest .fixture ()
887891async def foo_test2 ():
888892 yield
893+
894+
895+ async def comprehensions ():
896+ # guaranteed iteration with await in test
897+ [... for x in range (10 ) if await foo ()]
898+ yield # safe
899+
900+ # guaranteed iteration and await in value, but test is not guaranteed
901+ [await foo () for x in range (10 ) if bar ()]
902+ yield # error: 4, "yield", Stmt("yield", line-4)
903+
904+ # guaranteed iteration and await in value
905+ [await foo () for x in range (10 )]
906+ yield # safe
907+
908+ # not guaranteed to iter
909+ [await foo () for x in bar ()]
910+ yield # error: 4, "yield", Stmt("yield", line-4)
911+
912+ # await statement in loop expression
913+ [... for x in bar (await foo ())]
914+ yield
915+
916+ # set comprehensions use same logic as list
917+ {await foo () for x in range (10 )}
918+ yield # safe
919+
920+ {await foo () for x in bar ()}
921+ yield # error: 4, "yield", Stmt("yield", line-3)
922+
923+ # dict comprehensions use same logic as list
924+ {await foo (): 5 for x in bar ()}
925+ yield # error: 4, "yield", Stmt("yield", line-4)
926+
927+ # other than `await` can be in both key&val
928+ {await foo (): 5 for x in range (10 )}
929+ yield
930+
931+ {5 : await foo () for x in range (10 )}
932+ yield
933+
934+ # generator expressions are never treated as safe
935+ (await foo () for x in range (10 ))
936+ yield # error: 4, "yield", Stmt("yield", line-4)
937+
938+ (await foo () for x in bar () if await foo ())
939+ yield # error: 4, "yield", Stmt("yield", line-3)
940+
941+ # async for always safe
942+ [... async for x in bar ()]
943+ yield # safe
944+ {... async for x in bar ()}
945+ yield # safe
946+ {...: ... async for x in bar ()}
947+ yield # safe
948+
949+ # other than in generator expression
950+ (... async for x in bar ())
951+ yield # error: 4, "yield", Stmt("yield", line-4)
952+
953+ # multiple loops
954+ [... for x in range (10 ) for y in range (10 ) if await foo ()]
955+ yield
956+ [... for x in range (10 ) for y in bar () if await foo ()]
957+ yield # error: 4, "yield", Stmt("yield", line-2)
958+ [... for x in bar () for y in range (10 ) if await foo ()]
959+ yield # error: 4, "yield", Stmt("yield", line-2)
960+
961+ [await foo () for x in range (10 ) for y in range (10 )]
962+ yield
963+ [await foo () for x in range (10 ) for y in bar ()]
964+ yield # error: 4, "yield", Stmt("yield", line-2)
965+ [await foo () for x in bar () for y in range (10 )]
966+ yield # error: 4, "yield", Stmt("yield", line-2)
967+
968+ # trip loops!
969+ [... for x in range (10 ) for y in range (10 ) async for z in bar ()]
970+ yield
971+ [... for x in range (10 ) for y in range (10 ) for z in range (10 )]
972+ yield # error: 4, "yield", Stmt("yield", line-2)
973+
974+ # multiple ifs
975+ [... for x in range (10 ) for y in range (10 ) if await foo () if await foo ()]
976+ yield
977+
978+ [... for x in range (10 ) for y in bar () if await foo () if await foo ()]
979+ yield # error: 4, "yield", Stmt("yield", line-3)
980+
981+ # nested comprehensions
982+ [[await foo () for x in range (10 )] for y in range (10 )]
983+ yield
984+
985+ # code coverage: inner comprehension with no checkpointed statements
986+ [... for x in [await foo ()] for y in x ]
0 commit comments