From a34c7d697f7d09fb7ce86b4ba36aaf589359d1ea Mon Sep 17 00:00:00 2001 From: khanak0509 Date: Fri, 5 Dec 2025 12:12:50 +0530 Subject: [PATCH 1/4] gh-142250: Add hasjforward and hasjback collections to opcode.py and document in dis.rst --- Doc/library/dis.rst | 20 +++++++++++++++++++- Lib/opcode.py | 20 +++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index a24589fd0a5af3..aa45dcb93287b0 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -813,18 +813,23 @@ not have to be) the original ``STACK[-2]``. .. versionadded:: 3.5 -.. opcode:: END_ASYNC_FOR +.. opcode:: END_ASYNC_FOR (delta) Terminates an :keyword:`async for` loop. Handles an exception raised when awaiting a next item. The stack contains the async iterable in ``STACK[-2]`` and the raised exception in ``STACK[-1]``. Both are popped. If the exception is not :exc:`StopAsyncIteration`, it is re-raised. + + Decrements the bytecode counter by *delta* to jump back to the loop start + if continuing iteration. .. versionadded:: 3.8 .. versionchanged:: 3.11 Exception representation on the stack now consist of one, not three, items. + .. versionchanged:: 3.14 + Added the *delta* parameter. This opcode is now a backward jump instruction. .. opcode:: CLEANUP_THROW @@ -2081,3 +2086,16 @@ instructions: .. deprecated:: 3.13 All jumps are now relative. This list is empty. + +.. data:: hasjforward + + Sequence of bytecodes that perform forward jumps. + + .. versionadded:: 3.14 + +.. data:: hasjback + + Sequence of bytecodes that perform backward jumps, such as + :opcode:`JUMP_BACKWARD`, :opcode:`FOR_ITER`, and :opcode:`END_ASYNC_FOR`. + + .. versionadded:: 3.14 diff --git a/Lib/opcode.py b/Lib/opcode.py index 0e9520b6832499..3ddeb2e68922a9 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -7,7 +7,7 @@ __all__ = ["cmp_op", "stack_effect", "hascompare", "opname", "opmap", "HAVE_ARGUMENT", "EXTENDED_ARG", "hasarg", "hasconst", "hasname", - "hasjump", "hasjrel", "hasjabs", "hasfree", "haslocal", "hasexc"] + "hasjump", "hasjrel", "hasjabs", "hasjforward", "hasjback", "hasfree", "haslocal", "hasexc"] import builtins import _opcode @@ -17,6 +17,18 @@ HAVE_ARGUMENT, MIN_INSTRUMENTED_OPCODE) # noqa: F401 EXTENDED_ARG = opmap['EXTENDED_ARG'] +def _is_backward_jump_op(op): + """Helper function to identify backward jump opcodes.""" + # Get the opcode name from the op number + op_name = opname[op] if op < len(opname) else None + return op_name in ( + 'JUMP_BACKWARD', + 'JUMP_BACKWARD_NO_INTERRUPT', + 'FOR_ITER', + 'END_ASYNC_FOR', + ) + + opname = ['<%r>' % (op,) for op in range(max(opmap.values()) + 1)] for m in (opmap, _specialized_opmap): for op, i in m.items(): @@ -35,6 +47,12 @@ haslocal = [op for op in opmap.values() if _opcode.has_local(op)] hasexc = [op for op in opmap.values() if _opcode.has_exc(op)] +hasjforward = [op for op in hasjump if not _is_backward_jump_op(op)] +hasjback = [op for op in hasjump if _is_backward_jump_op(op)] + + + +_intrinsic_1_descs = _opcode.get_intrinsic1_descs() _intrinsic_1_descs = _opcode.get_intrinsic1_descs() _intrinsic_2_descs = _opcode.get_intrinsic2_descs() From 9b913e48b640a0768d87114d18ef7a377fe30194 Mon Sep 17 00:00:00 2001 From: khanak0509 Date: Fri, 5 Dec 2025 14:48:18 +0530 Subject: [PATCH 2/4] Add NEWS entry for gh-142250 --- .../next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst diff --git a/Misc/NEWS.d/next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst b/Misc/NEWS.d/next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst new file mode 100644 index 00000000000000..0561d386a49e5a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst @@ -0,0 +1,2 @@ +Add :data:`~dis.hasjforward` and :data:`~dis.hasjback` opcode collections to +distinguish between forward and backward jump instructions. Patch by Khanak.Add :data:`~dis.hasjforward` and :data:`~dis.hasjback` opcode collections to distinguish between forward and backward jump instructions. Patch by Khanak. From 710bc9f0d307dc9d5a50fec7bee392af5c597ea6 Mon Sep 17 00:00:00 2001 From: khanak0509 Date: Fri, 5 Dec 2025 14:57:54 +0530 Subject: [PATCH 3/4] Fix linting: remove duplicate line and trailing whitespace --- Doc/library/dis.rst | 4 ++-- Lib/opcode.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index aa45dcb93287b0..618ff144b8080e 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -819,7 +819,7 @@ not have to be) the original ``STACK[-2]``. when awaiting a next item. The stack contains the async iterable in ``STACK[-2]`` and the raised exception in ``STACK[-1]``. Both are popped. If the exception is not :exc:`StopAsyncIteration`, it is re-raised. - + Decrements the bytecode counter by *delta* to jump back to the loop start if continuing iteration. @@ -2095,7 +2095,7 @@ instructions: .. data:: hasjback - Sequence of bytecodes that perform backward jumps, such as + Sequence of bytecodes that perform backward jumps, such as :opcode:`JUMP_BACKWARD`, :opcode:`FOR_ITER`, and :opcode:`END_ASYNC_FOR`. .. versionadded:: 3.14 diff --git a/Lib/opcode.py b/Lib/opcode.py index 3ddeb2e68922a9..eee04f712ce83b 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -52,7 +52,6 @@ def _is_backward_jump_op(op): -_intrinsic_1_descs = _opcode.get_intrinsic1_descs() _intrinsic_1_descs = _opcode.get_intrinsic1_descs() _intrinsic_2_descs = _opcode.get_intrinsic2_descs() From 7c98534f6f068e4e6ddcb770d3e00e7447d6d3e4 Mon Sep 17 00:00:00 2001 From: khanak0509 Date: Fri, 5 Dec 2025 15:18:16 +0530 Subject: [PATCH 4/4] Update NEWS fragment to END_ASYNC_FOR documentation fix --- .../Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst b/Misc/NEWS.d/next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst index 0561d386a49e5a..e524ede6772b89 100644 --- a/Misc/NEWS.d/next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst +++ b/Misc/NEWS.d/next/Library/2024-12-05-12-00-00.gh-issue-142250.xyz123.rst @@ -1,2 +1,4 @@ -Add :data:`~dis.hasjforward` and :data:`~dis.hasjback` opcode collections to -distinguish between forward and backward jump instructions. Patch by Khanak.Add :data:`~dis.hasjforward` and :data:`~dis.hasjback` opcode collections to distinguish between forward and backward jump instructions. Patch by Khanak. +Document the ``delta`` parameter for the :opcode:`!END_ASYNC_FOR` opcode in +Python 3.14. Add :data:`~dis.hasjforward` and :data:`~dis.hasjback` opcode +collections to distinguish between forward and backward jump instructions. +Patch by Khanak.