Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Lib/test/test_asyncgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -1835,6 +1835,13 @@ async def run():
res = self.loop.run_until_complete(run())
self.assertEqual(res, [i * 2 for i in range(1, 10)])

def test_async_gen_expression_incorrect(self):
err_msg_async = "'async for' requires an object with " \
"__aiter__ method, got .*"

with self.assertRaisesRegex(TypeError, err_msg_async):
(x async for x in None)

def test_asyncgen_nonstarted_hooks_are_cancellable(self):
# See https://bugs.python.org/issue38013
messages = []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Reverts the behavior of async generator expressions when created with object
w/o __aiter__ method to the pre-3.13 behavior of raising a TypeError.
12 changes: 8 additions & 4 deletions Python/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -4544,9 +4544,9 @@ codegen_async_comprehension_generator(compiler *c, location loc,
else {
/* Sub-iter - calculate on the fly */
VISIT(c, expr, gen->iter);
ADDOP(c, LOC(gen->iter), GET_AITER);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, is this change necessary? I think the test passes without it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. There was a bug in previous commit. I've reverted related logic in codegen.c.

}
}
ADDOP(c, LOC(gen->iter), GET_AITER);

USE_LABEL(c, start);
/* Runtime will push a block here, so we need to account for that */
Expand Down Expand Up @@ -4776,7 +4776,6 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
location loc = LOC(e);

outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
int is_sync_genexpr = type == COMP_GENEXP && !outermost->is_async;
if (is_inlined) {
VISIT(c, expr, outermost->iter);
if (push_inlined_comprehension_state(c, loc, entry, &inline_state)) {
Expand Down Expand Up @@ -4853,8 +4852,13 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
Py_CLEAR(co);

VISIT(c, expr, outermost->iter);
if (is_sync_genexpr) {
ADDOP(c, loc, GET_ITER);
if (type == COMP_GENEXP) {
if (outermost->is_async) {
ADDOP(c, loc, GET_AITER);
}
else {
ADDOP(c, loc, GET_ITER);
}
}
ADDOP_I(c, loc, CALL, 0);

Expand Down
Loading