GH-128534: Fix behavior of branch monitoring for `async for` (GH-130847) · python/cpython@89df62c · GitHub
Skip to content

Commit 89df62c

Browse files
authored
GH-128534: Fix behavior of branch monitoring for async for (GH-130847)
* Both branches in a pair now have a common source and are included in co_branches
1 parent e5527f2 commit 89df62c

17 files changed

Lines changed: 235 additions & 154 deletions

Include/internal/pycore_magic_number.h

Lines changed: 3 additions & 2 deletions

Include/internal/pycore_opcode_metadata.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/opcode_ids.h

Lines changed: 59 additions & 59 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/_opcode_metadata.py

Lines changed: 59 additions & 59 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/dis.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
STORE_FAST_STORE_FAST = opmap['STORE_FAST_STORE_FAST']
5353
IS_OP = opmap['IS_OP']
5454
CONTAINS_OP = opmap['CONTAINS_OP']
55+
END_ASYNC_FOR = opmap['END_ASYNC_FOR']
5556

5657
CACHE = opmap["CACHE"]
5758

@@ -605,7 +606,8 @@ def get_argval_argrepr(self, op, arg, offset):
605606
argval = self.offset_from_jump_arg(op, arg, offset)
606607
lbl = self.get_label_for_offset(argval)
607608
assert lbl is not None
608-
argrepr = f"to L{lbl}"
609+
preposition = "from" if deop == END_ASYNC_FOR else "to"
610+
argrepr = f"{preposition} L{lbl}"
609611
elif deop in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST):
610612
arg1 = arg >> 4
611613
arg2 = arg & 15
@@ -745,7 +747,8 @@ def _parse_exception_table(code):
745747

746748
def _is_backward_jump(op):
747749
return opname[op] in ('JUMP_BACKWARD',
748-
'JUMP_BACKWARD_NO_INTERRUPT')
750+
'JUMP_BACKWARD_NO_INTERRUPT',
751+
'END_ASYNC_FOR') # Not really a jump, but it has a "target"
749752

750753
def _get_instructions_bytes(code, linestarts=None, line_offset=0, co_positions=None,
751754
original_code=None, arg_resolver=None):

Lib/test/test_code.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,15 @@ def with_extended_args(x):
953953
get_line_branches(with_extended_args),
954954
[(1,2,8)])
955955

956+
async def afunc():
957+
async for letter in async_iter1:
958+
2
959+
3
960+
961+
self.assertEqual(
962+
get_line_branches(afunc),
963+
[(1,1,3)])
964+
956965
if check_impl_detail(cpython=True) and ctypes is not None:
957966
py = ctypes.pythonapi
958967
freefunc = ctypes.CFUNCTYPE(None,ctypes.c_voidp)

Lib/test/test_dis.py

Lines changed: 17 additions & 0 deletions

0 commit comments

Comments
 (0)