async def __aexit__(self, *exc_info):
self.output.append(-self.value)
+async def asynciter(iterable):
+ """Convert an iterable to an asynchronous iterator."""
+ for x in iterable:
+ yield x
# A very basic example. If this fails, we're in deep trouble.
output.append(6)
output.append(7)
+ @async_jump_test(4, 5, [3, 5])
+ async def test_jump_out_of_async_for_block_forwards(output):
+ for i in [1]:
+ async for i in asynciter([1, 2]):
+ output.append(3)
+ output.append(4)
+ output.append(5)
+
+ @async_jump_test(5, 2, [2, 4, 2, 4, 5, 6])
+ async def test_jump_out_of_async_for_block_backwards(output):
+ for i in [1]:
+ output.append(2)
+ async for i in asynciter([1]):
+ output.append(4)
+ output.append(5)
+ output.append(6)
+
@jump_test(1, 2, [3])
def test_jump_to_codeless_line(output):
output.append(1)
output.append(7)
output.append(8)
+ @async_jump_test(1, 7, [7, 8])
+ async def test_jump_over_async_for_block_before_else(output):
+ output.append(1)
+ if not output: # always false
+ async for i in asynciter([3]):
+ output.append(4)
+ else:
+ output.append(6)
+ output.append(7)
+ output.append(8)
+
# The second set of 'jump' tests are for things that are not allowed:
@jump_test(2, 3, [1], (ValueError, 'after'))
for i in 1, 2:
output.append(3)
+ @async_jump_test(1, 3, [], (ValueError, 'into'))
+ async def test_no_jump_forwards_into_async_for_block(output):
+ output.append(1)
+ async for i in asynciter([1, 2]):
+ output.append(3)
+
@jump_test(3, 2, [2, 2], (ValueError, 'into'))
def test_no_jump_backwards_into_for_block(output):
for i in 1, 2:
output.append(2)
output.append(3)
+ @async_jump_test(3, 2, [2, 2], (ValueError, 'into'))
+ async def test_no_jump_backwards_into_async_for_block(output):
+ async for i in asynciter([1, 2]):
+ output.append(2)
+ output.append(3)
+
@jump_test(2, 4, [], (ValueError, 'into'))
def test_no_jump_forwards_into_while_block(output):
i = 1
output.append(7)
output.append(8)
+ @async_jump_test(7, 4, [1, 6], (ValueError, 'into'))
+ async def test_no_jump_into_async_for_block_before_else(output):
+ output.append(1)
+ if not output: # always false
+ async for i in asynciter([3]):
+ output.append(4)
+ else:
+ output.append(6)
+ output.append(7)
+ output.append(8)
+
def test_no_jump_to_non_integers(self):
self.run_test(no_jump_to_non_integers, 2, "Spam", [True])
ADDOP(c, DUP_TOP);
ADDOP_O(c, LOAD_GLOBAL, stop_aiter_error, names);
ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);
- ADDOP_JABS(c, POP_JUMP_IF_FALSE, try_cleanup);
-
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_EXCEPT); /* for SETUP_EXCEPT */
- ADDOP(c, POP_TOP); /* for correct calculation of stack effect */
- ADDOP(c, POP_BLOCK); /* for SETUP_LOOP */
- ADDOP_JABS(c, JUMP_ABSOLUTE, after_loop_else);
-
-
- compiler_use_next_block(c, try_cleanup);
+ ADDOP_JABS(c, POP_JUMP_IF_TRUE, try_cleanup);
ADDOP(c, END_FINALLY);
compiler_use_next_block(c, after_try);
VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
ADDOP_JABS(c, JUMP_ABSOLUTE, try);
+ compiler_use_next_block(c, try_cleanup);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_EXCEPT); /* for SETUP_EXCEPT */
+ ADDOP(c, POP_TOP); /* for correct calculation of stack effect */
ADDOP(c, POP_BLOCK); /* for SETUP_LOOP */
compiler_pop_fblock(c, LOOP, try);
_Py_IDENTIFIER(StopAsyncIteration);
comprehension_ty gen;
- basicblock *anchor, *if_cleanup, *try,
+ basicblock *if_cleanup, *try,
*after_try, *except, *try_cleanup;
Py_ssize_t i, n;
try = compiler_new_block(c);
after_try = compiler_new_block(c);
- try_cleanup = compiler_new_block(c);
except = compiler_new_block(c);
if_cleanup = compiler_new_block(c);
- anchor = compiler_new_block(c);
+ try_cleanup = compiler_new_block(c);
- if (if_cleanup == NULL || anchor == NULL ||
+ if (if_cleanup == NULL ||
try == NULL || after_try == NULL ||
except == NULL || try_cleanup == NULL) {
return 0;
ADDOP(c, DUP_TOP);
ADDOP_O(c, LOAD_GLOBAL, stop_aiter_error, names);
ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);
- ADDOP_JABS(c, POP_JUMP_IF_FALSE, try_cleanup);
-
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_EXCEPT); /* for SETUP_EXCEPT */
- ADDOP_JABS(c, JUMP_ABSOLUTE, anchor);
-
-
- compiler_use_next_block(c, try_cleanup);
+ ADDOP_JABS(c, POP_JUMP_IF_TRUE, try_cleanup);
ADDOP(c, END_FINALLY);
compiler_use_next_block(c, after_try);
}
compiler_use_next_block(c, if_cleanup);
ADDOP_JABS(c, JUMP_ABSOLUTE, try);
- compiler_use_next_block(c, anchor);
+
+ compiler_use_next_block(c, try_cleanup);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP);
+ ADDOP(c, POP_EXCEPT); /* for SETUP_EXCEPT */
ADDOP(c, POP_TOP);
return 1;