diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-03-23 12:34:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-23 12:34:35 (GMT) |
commit | 702f8f3611bc49b73772cce2b9b041bd11ff9b35 (patch) | |
tree | f712f53a42dc54831e7daf7e3686bc9c875b37b3 /Lib/test/test_sys_settrace.py | |
parent | c65bf3fe4a2bde424b79e350f36b7aaa3f6476f6 (diff) | |
download | cpython-702f8f3611bc49b73772cce2b9b041bd11ff9b35.zip cpython-702f8f3611bc49b73772cce2b9b041bd11ff9b35.tar.gz cpython-702f8f3611bc49b73772cce2b9b041bd11ff9b35.tar.bz2 |
bpo-33041: Rework compiling an "async for" loop. (#6142)
* Added new opcode END_ASYNC_FOR.
* Setting global StopAsyncIteration no longer breaks "async for" loops.
* Jumping into an "async for" loop is now disabled.
* Jumping out of an "async for" loop no longer corrupts the stack.
* Simplify the compiler.
Diffstat (limited to 'Lib/test/test_sys_settrace.py')
-rw-r--r-- | Lib/test/test_sys_settrace.py | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 2587794..1fa43b2 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -33,6 +33,10 @@ class asynctracecontext: 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. @@ -720,6 +724,23 @@ class JumpTestCase(unittest.TestCase): 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) @@ -1030,6 +1051,17 @@ class JumpTestCase(unittest.TestCase): 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')) @@ -1081,12 +1113,24 @@ class JumpTestCase(unittest.TestCase): 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(1, 3, [], (ValueError, 'into')) def test_no_jump_forwards_into_with_block(output): output.append(1) @@ -1220,6 +1264,17 @@ class JumpTestCase(unittest.TestCase): 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]) |