Skip to content

Commit c1aa785

Browse files
committed
Fix async list comprehensions.
1 parent c010589 commit c1aa785

2 files changed

Lines changed: 37 additions & 12 deletions

File tree

Lib/test/test_listcomps.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,29 @@ def increment():
808808
[increment() for _ in range(5)]
809809
self.assertEqual(count, 5)
810810

811+
def test_async_optimization_with_side_effects(self):
812+
import asyncio
813+
814+
async def gen1(aiterator):
815+
with self.assertRaises(ZeroDivisionError):
816+
[0/0 async for _ in aiterator]
817+
818+
async def gen2(aiterator):
819+
[increment() async for _ in aiterator]
820+
821+
async def numbers():
822+
for i in range(5):
823+
yield i
824+
825+
count = 0
826+
def increment():
827+
nonlocal count
828+
count += 1
829+
830+
asyncio.run(gen1(numbers()))
831+
asyncio.run(gen2(numbers()))
832+
self.assertEqual(count, 5)
833+
811834
__test__ = {'doctests' : doctests}
812835

813836
def load_tests(loader, tests, pattern):

Python/codegen.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static int codegen_async_comprehension_generator(
247247
asdl_comprehension_seq *generators, int gen_index,
248248
int depth,
249249
expr_ty elt, expr_ty val, int type,
250-
IterStackPosition iter_pos);
250+
IterStackPosition iter_pos, bool avoid_creation);
251251

252252
static int codegen_pattern(compiler *, pattern_ty, pattern_context *);
253253
static int codegen_match(compiler *, stmt_ty);
@@ -4556,7 +4556,7 @@ codegen_comprehension_generator(compiler *c, location loc,
45564556
if (gen->is_async) {
45574557
return codegen_async_comprehension_generator(
45584558
c, loc, generators, gen_index, depth, elt, val, type,
4559-
iter_pos);
4559+
iter_pos, avoid_creation);
45604560
} else {
45614561
return codegen_sync_comprehension_generator(
45624562
c, loc, generators, gen_index, depth, elt, val, type,
@@ -4737,7 +4737,7 @@ codegen_async_comprehension_generator(compiler *c, location loc,
47374737
asdl_comprehension_seq *generators,
47384738
int gen_index, int depth,
47394739
expr_ty elt, expr_ty val, int type,
4740-
IterStackPosition iter_pos)
4740+
IterStackPosition iter_pos, bool avoid_creation)
47414741
{
47424742
NEW_JUMP_TARGET_LABEL(c, start);
47434743
NEW_JUMP_TARGET_LABEL(c, send);
@@ -4787,7 +4787,7 @@ codegen_async_comprehension_generator(compiler *c, location loc,
47874787
RETURN_IF_ERROR(
47884788
codegen_comprehension_generator(c, loc,
47894789
generators, gen_index, depth,
4790-
elt, val, type, 0, false));
4790+
elt, val, type, 0, avoid_creation));
47914791
}
47924792

47934793
location elt_loc = LOC(elt);
@@ -4796,6 +4796,7 @@ codegen_async_comprehension_generator(compiler *c, location loc,
47964796
/* comprehension specific code */
47974797
switch (type) {
47984798
case COMP_GENEXP:
4799+
assert(!avoid_creation);
47994800
if (elt->kind == Starred_kind) {
48004801
NEW_JUMP_TARGET_LABEL(c, unpack_start);
48014802
NEW_JUMP_TARGET_LABEL(c, unpack_end);
@@ -4817,6 +4818,11 @@ codegen_async_comprehension_generator(compiler *c, location loc,
48174818
}
48184819
break;
48194820
case COMP_LISTCOMP:
4821+
if (avoid_creation) {
4822+
VISIT(c, expr, elt);
4823+
ADDOP(c, elt_loc, POP_TOP);
4824+
break;
4825+
}
48204826
if (elt->kind == Starred_kind) {
48214827
VISIT(c, expr, elt->v.Starred.value);
48224828
ADDOP_I(c, elt_loc, LIST_EXTEND, depth + 1);
@@ -4827,6 +4833,7 @@ codegen_async_comprehension_generator(compiler *c, location loc,
48274833
}
48284834
break;
48294835
case COMP_SETCOMP:
4836+
assert(!avoid_creation);
48304837
if (elt->kind == Starred_kind) {
48314838
VISIT(c, expr, elt->v.Starred.value);
48324839
ADDOP_I(c, elt_loc, SET_UPDATE, depth + 1);
@@ -4837,6 +4844,7 @@ codegen_async_comprehension_generator(compiler *c, location loc,
48374844
}
48384845
break;
48394846
case COMP_DICTCOMP:
4847+
assert(!avoid_creation);
48404848
if (val == NULL) {
48414849
/* unpacking (**) case */
48424850
VISIT(c, expr, elt);
@@ -5156,19 +5164,13 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
51565164
}
51575165

51585166
static int
5159-
codegen_genexp_impl(compiler *c, expr_ty e, bool avoid_creation)
5167+
codegen_genexp(compiler *c, expr_ty e)
51605168
{
51615169
assert(e->kind == GeneratorExp_kind);
51625170
_Py_DECLARE_STR(anon_genexpr, "<genexpr>");
51635171
return codegen_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
51645172
e->v.GeneratorExp.generators,
5165-
e->v.GeneratorExp.elt, NULL, avoid_creation);
5166-
}
5167-
5168-
static int
5169-
codegen_genexp(compiler *c, expr_ty e)
5170-
{
5171-
return codegen_genexp_impl(c, e, false);
5173+
e->v.GeneratorExp.elt, NULL, false);
51725174
}
51735175

51745176
static int

0 commit comments

Comments
 (0)