Python-checkins
Threads by month
- ----- 2025 -----
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
January 2025
- 1 participants
- 181 discussions
GH-128533: Add `NOT_TAKEN` instruction after bytecode optimization. (GH-128554)
by markshannon 06 Jan '25
by markshannon 06 Jan '25
06 Jan '25
https://github.com/python/cpython/commit/2434fd2d50b8b770585ad5949a664e4bba…
commit: 2434fd2d50b8b770585ad5949a664e4bbab4bde1
branch: main
author: Mark Shannon <mark(a)hotpy.org>
committer: markshannon <mark(a)hotpy.org>
date: 2025-01-06T22:01:07Z
summary:
GH-128533: Add `NOT_TAKEN` instruction after bytecode optimization. (GH-128554)
files:
M Lib/test/test_compiler_codegen.py
M Lib/test/test_dis.py
M Python/codegen.c
M Python/flowgraph.c
diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py
index 5655e1b9cf196a..cf5e2d901db4de 100644
--- a/Lib/test/test_compiler_codegen.py
+++ b/Lib/test/test_compiler_codegen.py
@@ -29,7 +29,6 @@ def test_if_expression(self):
('LOAD_CONST', 0, 1),
('TO_BOOL', 0, 1),
('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1),
- ('NOT_TAKEN', None, 1),
('LOAD_SMALL_INT', 42, 1),
('JUMP_NO_INTERRUPT', exit_lbl := self.Label()),
false_lbl,
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index e733a673d003e7..76d9b5401d7d8e 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -200,8 +200,7 @@ def bug1333982(x=[]):
dis_bug1333982 = """\
%3d RESUME 0
-%3d NOT_TAKEN
- LOAD_COMMON_CONSTANT 0 (AssertionError)
+%3d LOAD_COMMON_CONSTANT 0 (AssertionError)
LOAD_CONST 0 (<code object <genexpr> at 0x..., file "%s", line %d>)
MAKE_FUNCTION
LOAD_FAST 0 (x)
@@ -433,7 +432,7 @@ def foo(a: int, b: str) -> str:
1 LOAD_SMALL_INT 0
STORE_NAME 0 (x)
- 2 L1: NOT_TAKEN
+ 2 L1: NOP
3 LOAD_NAME 0 (x)
LOAD_SMALL_INT 1
@@ -648,11 +647,11 @@ async def _asyncwith(c):
L20: CLEANUP_THROW
L21: END_SEND
TO_BOOL
- POP_JUMP_IF_TRUE 2 (to L22)
- NOT_TAKEN
- RERAISE 2
- L22: POP_TOP
- L23: POP_EXCEPT
+ POP_JUMP_IF_TRUE 2 (to L24)
+ L22: NOT_TAKEN
+ L23: RERAISE 2
+ L24: POP_TOP
+ L25: POP_EXCEPT
POP_TOP
POP_TOP
POP_TOP
@@ -662,24 +661,25 @@ async def _asyncwith(c):
LOAD_CONST 0 (None)
RETURN_VALUE
- -- L24: COPY 3
+ -- L26: COPY 3
POP_EXCEPT
RERAISE 1
- L25: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR)
+ L27: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR)
RERAISE 1
ExceptionTable:
- L1 to L3 -> L25 [0] lasti
+ L1 to L3 -> L27 [0] lasti
L3 to L4 -> L12 [4]
- L4 to L6 -> L25 [0] lasti
+ L4 to L6 -> L27 [0] lasti
L6 to L7 -> L16 [2] lasti
- L7 to L9 -> L25 [0] lasti
+ L7 to L9 -> L27 [0] lasti
L9 to L10 -> L14 [2]
- L10 to L13 -> L25 [0] lasti
- L14 to L15 -> L25 [0] lasti
- L16 to L18 -> L24 [4] lasti
+ L10 to L13 -> L27 [0] lasti
+ L14 to L15 -> L27 [0] lasti
+ L16 to L18 -> L26 [4] lasti
L18 to L19 -> L20 [7]
- L19 to L23 -> L24 [4] lasti
- L23 to L25 -> L25 [0] lasti
+ L19 to L22 -> L26 [4] lasti
+ L23 to L25 -> L26 [4] lasti
+ L25 to L27 -> L27 [0] lasti
""" % (_asyncwith.__code__.co_firstlineno,
_asyncwith.__code__.co_firstlineno + 1,
_asyncwith.__code__.co_firstlineno + 2,
@@ -1777,7 +1777,7 @@ def _prepare_test_cases():
Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=10, argval=10, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='GET_ITER', opcode=16, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='FOR_ITER', opcode=69, arg=33, argval=94, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='FOR_ITER', opcode=69, arg=32, argval=92, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
@@ -1795,113 +1795,111 @@ def _prepare_test_cases():
Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=88, argrepr='to L3', offset=78, start_offset=78, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=82, start_offset=82, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
Instruction(opname='JUMP_BACKWARD', opcode=74, arg=32, argval=24, argrepr='to L1', offset=84, start_offset=84, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=None, label=3, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=90, start_offset=90, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_FORWARD', opcode=76, arg=13, argval=120, argrepr='to L5', offset=92, start_offset=92, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
- Instruction(opname='END_FOR', opcode=9, arg=None, argval=None, argrepr='', offset=94, start_offset=94, starts_line=True, line_number=3, label=4, positions=None, cache_info=None),
- Instruction(opname='POP_ITER', opcode=30, arg=None, argval=None, argrepr='', offset=96, start_offset=96, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=98, start_offset=98, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=108, start_offset=108, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=118, start_offset=118, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST_CHECK', opcode=85, arg=0, argval='i', argrepr='i', offset=120, start_offset=120, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
- Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=37, argval=208, argrepr='to L8', offset=130, start_offset=130, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=134, start_offset=134, starts_line=False, line_number=11, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=136, start_offset=136, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=146, start_offset=146, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=148, start_offset=148, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=156, start_offset=156, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=160, start_offset=160, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='BINARY_OP', opcode=44, arg=23, argval=23, argrepr='-=', offset=162, start_offset=162, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=166, start_offset=166, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=168, start_offset=168, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=6, argval=6, argrepr='', offset=170, start_offset=170, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=172, start_offset=172, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=3, argval=186, argrepr='to L6', offset=176, start_offset=176, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=180, start_offset=180, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=74, arg=33, argval=120, argrepr='to L5', offset=182, start_offset=182, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=186, start_offset=186, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=4, argval=4, argrepr='', offset=188, start_offset=188, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=190, start_offset=190, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=204, argrepr='to L7', offset=194, start_offset=194, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=198, start_offset=198, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=74, arg=42, argval=120, argrepr='to L5', offset=200, start_offset=200, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=204, start_offset=204, starts_line=True, line_number=None, label=7, positions=None, cache_info=None),
- Instruction(opname='JUMP_FORWARD', opcode=76, arg=11, argval=230, argrepr='to L9', offset=206, start_offset=206, starts_line=True, line_number=17, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=208, start_offset=208, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=218, start_offset=218, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=220, start_offset=220, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=228, start_offset=228, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
- Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=230, start_offset=230, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=232, start_offset=232, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=0, argval=0, argrepr='', offset=234, start_offset=234, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='BINARY_OP', opcode=44, arg=11, argval=11, argrepr='/', offset=236, start_offset=236, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=240, start_offset=240, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=242, start_offset=242, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=59, arg=1, argval=1, argrepr='', offset=244, start_offset=244, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=92, arg=1, argval=1, argrepr='__exit__', offset=246, start_offset=246, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='SWAP', opcode=114, arg=2, argval=2, argrepr='', offset=248, start_offset=248, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='SWAP', opcode=114, arg=3, argval=3, argrepr='', offset=250, start_offset=250, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=92, arg=0, argval=0, argrepr='__enter__', offset=252, start_offset=252, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=0, argval=0, argrepr='', offset=254, start_offset=254, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='STORE_FAST', opcode=109, arg=1, argval='dodgy', argrepr='dodgy', offset=262, start_offset=262, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=264, start_offset=264, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=274, start_offset=274, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=276, start_offset=276, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=284, start_offset=284, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=286, start_offset=286, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=288, start_offset=288, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=290, start_offset=290, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=3, argval=3, argrepr='', offset=292, start_offset=292, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=300, start_offset=300, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=302, start_offset=302, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=312, start_offset=312, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=314, start_offset=314, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=322, start_offset=322, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=324, start_offset=324, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='WITH_EXCEPT_START', opcode=43, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=348, argrepr='to L11', offset=340, start_offset=340, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=25, label=11, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=350, start_offset=350, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=8, label=3, positions=None, cache_info=None),
+ Instruction(opname='JUMP_FORWARD', opcode=76, arg=13, argval=118, argrepr='to L5', offset=90, start_offset=90, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='END_FOR', opcode=9, arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=True, line_number=3, label=4, positions=None, cache_info=None),
+ Instruction(opname='POP_ITER', opcode=30, arg=None, argval=None, argrepr='', offset=94, start_offset=94, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=96, start_offset=96, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=106, start_offset=106, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=108, start_offset=108, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=116, start_offset=116, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST_CHECK', opcode=85, arg=0, argval='i', argrepr='i', offset=118, start_offset=118, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
+ Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=120, start_offset=120, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=36, argval=204, argrepr='to L8', offset=128, start_offset=128, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=132, start_offset=132, starts_line=False, line_number=11, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=134, start_offset=134, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=144, start_offset=144, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=146, start_offset=146, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=154, start_offset=154, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=158, start_offset=158, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='BINARY_OP', opcode=44, arg=23, argval=23, argrepr='-=', offset=160, start_offset=160, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=164, start_offset=164, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=166, start_offset=166, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=6, argval=6, argrepr='', offset=168, start_offset=168, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=170, start_offset=170, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=3, argval=184, argrepr='to L6', offset=174, start_offset=174, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=178, start_offset=178, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=33, argval=118, argrepr='to L5', offset=180, start_offset=180, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=184, start_offset=184, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=4, argval=4, argrepr='', offset=186, start_offset=186, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=188, start_offset=188, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=202, argrepr='to L7', offset=192, start_offset=192, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=196, start_offset=196, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=42, argval=118, argrepr='to L5', offset=198, start_offset=198, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='JUMP_FORWARD', opcode=76, arg=11, argval=226, argrepr='to L9', offset=202, start_offset=202, starts_line=True, line_number=17, label=7, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=204, start_offset=204, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=214, start_offset=214, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=216, start_offset=216, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=224, start_offset=224, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
+ Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=228, start_offset=228, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=0, argval=0, argrepr='', offset=230, start_offset=230, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='BINARY_OP', opcode=44, arg=11, argval=11, argrepr='/', offset=232, start_offset=232, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=236, start_offset=236, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=238, start_offset=238, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=1, argval=1, argrepr='', offset=240, start_offset=240, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=92, arg=1, argval=1, argrepr='__exit__', offset=242, start_offset=242, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='SWAP', opcode=114, arg=2, argval=2, argrepr='', offset=244, start_offset=244, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='SWAP', opcode=114, arg=3, argval=3, argrepr='', offset=246, start_offset=246, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=92, arg=0, argval=0, argrepr='__enter__', offset=248, start_offset=248, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=0, argval=0, argrepr='', offset=250, start_offset=250, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=109, arg=1, argval='dodgy', argrepr='dodgy', offset=258, start_offset=258, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=260, start_offset=260, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=270, start_offset=270, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=272, start_offset=272, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=280, start_offset=280, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=282, start_offset=282, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=284, start_offset=284, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=286, start_offset=286, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=3, argval=3, argrepr='', offset=288, start_offset=288, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=298, start_offset=298, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=308, start_offset=308, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=318, start_offset=318, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=320, start_offset=320, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=322, start_offset=322, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=324, start_offset=324, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='WITH_EXCEPT_START', opcode=43, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=344, argrepr='to L11', offset=336, start_offset=336, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=25, label=11, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=350, start_offset=350, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=352, start_offset=352, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=354, start_offset=354, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=29, argval=302, argrepr='to L10', offset=358, start_offset=358, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=360, start_offset=360, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=364, start_offset=364, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=368, start_offset=368, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='CHECK_EXC_MATCH', opcode=5, arg=None, argval=None, argrepr='', offset=378, start_offset=378, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=414, argrepr='to L12', offset=380, start_offset=380, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=388, start_offset=388, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=398, start_offset=398, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=408, start_offset=408, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=410, start_offset=410, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=56, argval=302, argrepr='to L10', offset=412, start_offset=412, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=414, start_offset=414, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=416, start_offset=416, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=418, start_offset=418, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=420, start_offset=420, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=424, start_offset=424, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=434, start_offset=434, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=436, start_offset=436, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=444, start_offset=444, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=446, start_offset=446, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=448, start_offset=448, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=450, start_offset=450, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=452, start_offset=452, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=29, argval=298, argrepr='to L10', offset=354, start_offset=354, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=356, start_offset=356, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=358, start_offset=358, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=360, start_offset=360, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=364, start_offset=364, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='CHECK_EXC_MATCH', opcode=5, arg=None, argval=None, argrepr='', offset=374, start_offset=374, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=410, argrepr='to L12', offset=376, start_offset=376, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=380, start_offset=380, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=382, start_offset=382, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=384, start_offset=384, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=394, start_offset=394, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=404, start_offset=404, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=406, start_offset=406, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=56, argval=298, argrepr='to L10', offset=408, start_offset=408, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=410, start_offset=410, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=412, start_offset=412, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=416, start_offset=416, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=418, start_offset=418, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=420, start_offset=420, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=430, start_offset=430, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=432, start_offset=432, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=440, start_offset=440, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=442, start_offset=442, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=444, start_offset=444, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=446, start_offset=446, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=448, start_offset=448, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
]
# One last piece of inspect fodder to check the default line number handling
diff --git a/Python/codegen.c b/Python/codegen.c
index 14f9f5ad1254f5..61707ba677097c 100644
--- a/Python/codegen.c
+++ b/Python/codegen.c
@@ -406,13 +406,7 @@ codegen_addop_j(instr_sequence *seq, location loc,
assert(IS_JUMP_TARGET_LABEL(target));
assert(OPCODE_HAS_JUMP(opcode) || IS_BLOCK_PUSH_OPCODE(opcode));
assert(!IS_ASSEMBLER_OPCODE(opcode));
- if (_PyInstructionSequence_Addop(seq, opcode, target.id, loc) != SUCCESS) {
- return ERROR;
- }
- if (IS_CONDITIONAL_JUMP_OPCODE(opcode)) {
- return _PyInstructionSequence_Addop(seq, NOT_TAKEN, 0, NO_LOCATION);
- }
- return SUCCESS;
+ return _PyInstructionSequence_Addop(seq, opcode, target.id, loc);
}
#define ADDOP_JUMP(C, LOC, OP, O) \
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index 64df6290de06ba..017216aadd1f01 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -522,14 +522,15 @@ no_redundant_jumps(cfg_builder *g) {
static int
normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
cfg_instr *last = basicblock_last_instr(b);
- if (last == NULL || !is_jump(last) ||
- IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
+ if (last == NULL || !IS_CONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
return SUCCESS;
}
assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
bool is_forward = last->i_target->b_visited == 0;
if (is_forward) {
+ RETURN_IF_ERROR(
+ basicblock_addop(b, NOT_TAKEN, 0, last->i_loc));
return SUCCESS;
}
@@ -557,10 +558,6 @@ normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
if (backwards_jump == NULL) {
return ERROR;
}
- assert(b->b_next->b_iused > 0);
- assert(b->b_next->b_instr[0].i_opcode == NOT_TAKEN);
- b->b_next->b_instr[0].i_opcode = NOP;
- b->b_next->b_instr[0].i_loc = NO_LOCATION;
RETURN_IF_ERROR(
basicblock_addop(backwards_jump, NOT_TAKEN, 0, last->i_loc));
RETURN_IF_ERROR(
1
0
[3.12] gh-90241: Clarify documentation for PyUnicode_FSConverter and PyUnicode_FSDecoder (GH-128451) (GH-128543)
by serhiy-storchaka 06 Jan '25
by serhiy-storchaka 06 Jan '25
06 Jan '25
https://github.com/python/cpython/commit/8788a9570f033a293f7771bd5efa147173…
commit: 8788a9570f033a293f7771bd5efa1471734676bd
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2025-01-06T23:20:55+02:00
summary:
[3.12] gh-90241: Clarify documentation for PyUnicode_FSConverter and PyUnicode_FSDecoder (GH-128451) (GH-128543)
(cherry picked from commit 657d7b77e5c69967e9c0000b986fa4872d13958c)
Co-authored-by: Serhiy Storchaka <storchaka(a)gmail.com>
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland(a)users.noreply.github.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland(a)protonmail.com>
files:
M Doc/c-api/arg.rst
M Doc/c-api/unicode.rst
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index f9a2a5f3ed9da5..76a197bbec73e4 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -319,7 +319,7 @@ Other objects
.. _o_ampersand:
-``O&`` (object) [*converter*, *anything*]
+``O&`` (object) [*converter*, *address*]
Convert a Python object to a C variable through a *converter* function. This
takes two arguments: the first is a function, the second is the address of a C
variable (of arbitrary type), converted to :c:expr:`void *`. The *converter*
@@ -333,14 +333,20 @@ Other objects
the conversion has failed. When the conversion fails, the *converter* function
should raise an exception and leave the content of *address* unmodified.
- If the *converter* returns ``Py_CLEANUP_SUPPORTED``, it may get called a
+ .. c:macro:: Py_CLEANUP_SUPPORTED
+ :no-typesetting:
+
+ If the *converter* returns :c:macro:`!Py_CLEANUP_SUPPORTED`, it may get called a
second time if the argument parsing eventually fails, giving the converter a
chance to release any memory that it had already allocated. In this second
call, the *object* parameter will be ``NULL``; *address* will have the same value
as in the original call.
+ Examples of converters: :c:func:`PyUnicode_FSConverter` and
+ :c:func:`PyUnicode_FSDecoder`.
+
.. versionchanged:: 3.1
- ``Py_CLEANUP_SUPPORTED`` was added.
+ :c:macro:`!Py_CLEANUP_SUPPORTED` was added.
``p`` (:class:`bool`) [int]
Tests the value passed in for truth (a boolean **p**\ redicate) and converts
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 4d9f9ce02013b5..9b49569ad271b0 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -770,16 +770,25 @@ Functions encoding to and decoding from the :term:`filesystem encoding and
error handler` (:pep:`383` and :pep:`529`).
To encode file names to :class:`bytes` during argument parsing, the ``"O&"``
-converter should be used, passing :c:func:`PyUnicode_FSConverter` as the
+converter should be used, passing :c:func:`!PyUnicode_FSConverter` as the
conversion function:
.. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result)
- ParseTuple converter: encode :class:`str` objects -- obtained directly or
+ :ref:`PyArg_Parse\* converter <arg-parsing>`: encode :class:`str` objects -- obtained directly or
through the :class:`os.PathLike` interface -- to :class:`bytes` using
:c:func:`PyUnicode_EncodeFSDefault`; :class:`bytes` objects are output as-is.
- *result* must be a :c:expr:`PyBytesObject*` which must be released when it is
- no longer used.
+ *result* must be an address of a C variable of type :c:expr:`PyObject*`
+ (or :c:expr:`PyBytesObject*`).
+ On success, set the variable to a new :term:`strong reference` to
+ a :ref:`bytes object <bytesobjects>` which must be released
+ when it is no longer used and return a non-zero value
+ (:c:macro:`Py_CLEANUP_SUPPORTED`).
+ Embedded null bytes are not allowed in the result.
+ On failure, return ``0`` with an exception set.
+
+ If *obj* is ``NULL``, the function releases a strong reference
+ stored in the variable referred by *result* and returns ``1``.
.. versionadded:: 3.1
@@ -787,16 +796,26 @@ conversion function:
Accepts a :term:`path-like object`.
To decode file names to :class:`str` during argument parsing, the ``"O&"``
-converter should be used, passing :c:func:`PyUnicode_FSDecoder` as the
+converter should be used, passing :c:func:`!PyUnicode_FSDecoder` as the
conversion function:
.. c:function:: int PyUnicode_FSDecoder(PyObject* obj, void* result)
- ParseTuple converter: decode :class:`bytes` objects -- obtained either
+ :ref:`PyArg_Parse\* converter <arg-parsing>`: decode :class:`bytes` objects -- obtained either
directly or indirectly through the :class:`os.PathLike` interface -- to
:class:`str` using :c:func:`PyUnicode_DecodeFSDefaultAndSize`; :class:`str`
- objects are output as-is. *result* must be a :c:expr:`PyUnicodeObject*` which
- must be released when it is no longer used.
+ objects are output as-is.
+ *result* must be an address of a C variable of type :c:expr:`PyObject*`
+ (or :c:expr:`PyUnicodeObject*`).
+ On success, set the variable to a new :term:`strong reference` to
+ a :ref:`Unicode object <unicodeobjects>` which must be released
+ when it is no longer used and return a non-zero value
+ (:c:macro:`Py_CLEANUP_SUPPORTED`).
+ Embedded null characters are not allowed in the result.
+ On failure, return ``0`` with an exception set.
+
+ If *obj* is ``NULL``, release the strong reference
+ to the object referred to by *result* and return ``1``.
.. versionadded:: 3.2
1
0
[3.13] gh-90241: Clarify documentation for PyUnicode_FSConverter and PyUnicode_FSDecoder (GH-128451) (GH-128542)
by serhiy-storchaka 06 Jan '25
by serhiy-storchaka 06 Jan '25
06 Jan '25
https://github.com/python/cpython/commit/a194fd08c035578aafaf84e75d7b75c718…
commit: a194fd08c035578aafaf84e75d7b75c7185c37c6
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2025-01-06T23:20:26+02:00
summary:
[3.13] gh-90241: Clarify documentation for PyUnicode_FSConverter and PyUnicode_FSDecoder (GH-128451) (GH-128542)
(cherry picked from commit 657d7b77e5c69967e9c0000b986fa4872d13958c)
Co-authored-by: Serhiy Storchaka <storchaka(a)gmail.com>
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland(a)users.noreply.github.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland(a)protonmail.com>
files:
M Doc/c-api/arg.rst
M Doc/c-api/unicode.rst
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 41c0366d205086..209056ef2f8bce 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -319,7 +319,7 @@ Other objects
.. _o_ampersand:
-``O&`` (object) [*converter*, *anything*]
+``O&`` (object) [*converter*, *address*]
Convert a Python object to a C variable through a *converter* function. This
takes two arguments: the first is a function, the second is the address of a C
variable (of arbitrary type), converted to :c:expr:`void *`. The *converter*
@@ -333,14 +333,20 @@ Other objects
the conversion has failed. When the conversion fails, the *converter* function
should raise an exception and leave the content of *address* unmodified.
- If the *converter* returns ``Py_CLEANUP_SUPPORTED``, it may get called a
+ .. c:macro:: Py_CLEANUP_SUPPORTED
+ :no-typesetting:
+
+ If the *converter* returns :c:macro:`!Py_CLEANUP_SUPPORTED`, it may get called a
second time if the argument parsing eventually fails, giving the converter a
chance to release any memory that it had already allocated. In this second
call, the *object* parameter will be ``NULL``; *address* will have the same value
as in the original call.
+ Examples of converters: :c:func:`PyUnicode_FSConverter` and
+ :c:func:`PyUnicode_FSDecoder`.
+
.. versionchanged:: 3.1
- ``Py_CLEANUP_SUPPORTED`` was added.
+ :c:macro:`!Py_CLEANUP_SUPPORTED` was added.
``p`` (:class:`bool`) [int]
Tests the value passed in for truth (a boolean **p**\ redicate) and converts
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index d0a1b9ca1260bd..30592980968942 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -786,16 +786,25 @@ Functions encoding to and decoding from the :term:`filesystem encoding and
error handler` (:pep:`383` and :pep:`529`).
To encode file names to :class:`bytes` during argument parsing, the ``"O&"``
-converter should be used, passing :c:func:`PyUnicode_FSConverter` as the
+converter should be used, passing :c:func:`!PyUnicode_FSConverter` as the
conversion function:
.. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result)
- ParseTuple converter: encode :class:`str` objects -- obtained directly or
+ :ref:`PyArg_Parse\* converter <arg-parsing>`: encode :class:`str` objects -- obtained directly or
through the :class:`os.PathLike` interface -- to :class:`bytes` using
:c:func:`PyUnicode_EncodeFSDefault`; :class:`bytes` objects are output as-is.
- *result* must be a :c:expr:`PyBytesObject*` which must be released when it is
- no longer used.
+ *result* must be an address of a C variable of type :c:expr:`PyObject*`
+ (or :c:expr:`PyBytesObject*`).
+ On success, set the variable to a new :term:`strong reference` to
+ a :ref:`bytes object <bytesobjects>` which must be released
+ when it is no longer used and return a non-zero value
+ (:c:macro:`Py_CLEANUP_SUPPORTED`).
+ Embedded null bytes are not allowed in the result.
+ On failure, return ``0`` with an exception set.
+
+ If *obj* is ``NULL``, the function releases a strong reference
+ stored in the variable referred by *result* and returns ``1``.
.. versionadded:: 3.1
@@ -803,16 +812,26 @@ conversion function:
Accepts a :term:`path-like object`.
To decode file names to :class:`str` during argument parsing, the ``"O&"``
-converter should be used, passing :c:func:`PyUnicode_FSDecoder` as the
+converter should be used, passing :c:func:`!PyUnicode_FSDecoder` as the
conversion function:
.. c:function:: int PyUnicode_FSDecoder(PyObject* obj, void* result)
- ParseTuple converter: decode :class:`bytes` objects -- obtained either
+ :ref:`PyArg_Parse\* converter <arg-parsing>`: decode :class:`bytes` objects -- obtained either
directly or indirectly through the :class:`os.PathLike` interface -- to
:class:`str` using :c:func:`PyUnicode_DecodeFSDefaultAndSize`; :class:`str`
- objects are output as-is. *result* must be a :c:expr:`PyUnicodeObject*` which
- must be released when it is no longer used.
+ objects are output as-is.
+ *result* must be an address of a C variable of type :c:expr:`PyObject*`
+ (or :c:expr:`PyUnicodeObject*`).
+ On success, set the variable to a new :term:`strong reference` to
+ a :ref:`Unicode object <unicodeobjects>` which must be released
+ when it is no longer used and return a non-zero value
+ (:c:macro:`Py_CLEANUP_SUPPORTED`).
+ Embedded null characters are not allowed in the result.
+ On failure, return ``0`` with an exception set.
+
+ If *obj* is ``NULL``, release the strong reference
+ to the object referred to by *result* and return ``1``.
.. versionadded:: 3.2
1
0
https://github.com/python/cpython/commit/b6c919b674549d519efbbc378588ca6d3e…
commit: b6c919b674549d519efbbc378588ca6d3efc7242
branch: main
author: Hood Chatham <roberthoodchatham(a)gmail.com>
committer: FFY00 <filipe.lains(a)gmail.com>
date: 2025-01-06T19:45:14Z
summary:
gh-127146: Fix test_sysconfigdata_json for Emscripten (#128556)
files:
M Lib/sysconfig/__init__.py
diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py
index ed7b6a335d01d4..20d506bcd45abc 100644
--- a/Lib/sysconfig/__init__.py
+++ b/Lib/sysconfig/__init__.py
@@ -485,10 +485,10 @@ def _init_config_vars():
_init_posix(_CONFIG_VARS)
# If we are cross-compiling, load the prefixes from the Makefile instead.
if '_PYTHON_PROJECT_BASE' in os.environ:
- prefix = _CONFIG_VARS['prefix']
- exec_prefix = _CONFIG_VARS['exec_prefix']
- base_prefix = _CONFIG_VARS['prefix']
- base_exec_prefix = _CONFIG_VARS['exec_prefix']
+ prefix = _CONFIG_VARS['host_prefix']
+ exec_prefix = _CONFIG_VARS['host_exec_prefix']
+ base_prefix = _CONFIG_VARS['host_prefix']
+ base_exec_prefix = _CONFIG_VARS['host_exec_prefix']
abiflags = _CONFIG_VARS['ABIFLAGS']
# Normalized versions of prefix and exec_prefix are handy to have;
1
0
https://github.com/python/cpython/commit/f826beca0cedb8e4b92896544c75fd0d9d…
commit: f826beca0cedb8e4b92896544c75fd0d9dcb0446
branch: main
author: Mark Shannon <mark(a)hotpy.org>
committer: markshannon <mark(a)hotpy.org>
date: 2025-01-06T17:54:47Z
summary:
GH-128375: Better instrument for `FOR_ITER` (GH-128445)
files:
M Include/internal/pycore_instruments.h
M Include/internal/pycore_magic_number.h
M Include/internal/pycore_opcode_metadata.h
M Include/internal/pycore_uop_ids.h
M Include/internal/pycore_uop_metadata.h
M Include/opcode_ids.h
M Lib/_opcode_metadata.py
M Lib/test/test_code.py
M Lib/test/test_compiler_codegen.py
M Lib/test/test_dis.py
M Lib/test/test_monitoring.py
M Modules/_testcapimodule.c
M Programs/test_frozenmain.h
M Python/bytecodes.c
M Python/ceval_macros.h
M Python/codegen.c
M Python/executor_cases.c.h
M Python/generated_cases.c.h
M Python/instrumentation.c
M Python/opcode_targets.h
M Python/optimizer.c
M Python/optimizer_cases.c.h
M Tools/cases_generator/analyzer.py
M Tools/cases_generator/generators_common.py
M Tools/cases_generator/lexer.py
M Tools/cases_generator/opcode_metadata_generator.py
M Tools/cases_generator/tier1_generator.py
diff --git a/Include/internal/pycore_instruments.h b/Include/internal/pycore_instruments.h
index 4e5b374968ea98..92d8f056f402fc 100644
--- a/Include/internal/pycore_instruments.h
+++ b/Include/internal/pycore_instruments.h
@@ -48,8 +48,8 @@ _Py_call_instrumentation_instruction(
_Py_CODEUNIT *
_Py_call_instrumentation_jump(
- PyThreadState *tstate, int event,
- _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *target);
+ _Py_CODEUNIT *instr, PyThreadState *tstate, int event,
+ _PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest);
extern int
_Py_call_instrumentation_arg(PyThreadState *tstate, int event,
diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h
index ec3685d2034560..f9f71d7453331e 100644
--- a/Include/internal/pycore_magic_number.h
+++ b/Include/internal/pycore_magic_number.h
@@ -264,6 +264,7 @@ Known values:
Python 3.14a2 3609 (Add LOAD_SMALL_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST)
Python 3.14a4 3610 (Add VALUE_WITH_FAKE_GLOBALS format to annotationlib)
Python 3.14a4 3611 (Add NOT_TAKEN instruction)
+ Python 3.14a4 3612 (Add POP_ITER and INSTRUMENTED_POP_ITER)
Python 3.15 will start with 3650
@@ -276,7 +277,7 @@ PC/launcher.c must also be updated.
*/
-#define PYC_MAGIC_NUMBER 3611
+#define PYC_MAGIC_NUMBER 3612
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index 5fb236836dccd9..90d5e277d8d6ce 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -245,6 +245,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 0;
case INSTRUMENTED_NOT_TAKEN:
return 0;
+ case INSTRUMENTED_POP_ITER:
+ return 1;
case INSTRUMENTED_POP_JUMP_IF_FALSE:
return 0;
case INSTRUMENTED_POP_JUMP_IF_NONE:
@@ -375,6 +377,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 0;
case POP_EXCEPT:
return 1;
+ case POP_ITER:
+ return 1;
case POP_JUMP_IF_FALSE:
return 1;
case POP_JUMP_IF_NONE:
@@ -708,6 +712,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 0;
case INSTRUMENTED_NOT_TAKEN:
return 0;
+ case INSTRUMENTED_POP_ITER:
+ return 0;
case INSTRUMENTED_POP_JUMP_IF_FALSE:
return 0;
case INSTRUMENTED_POP_JUMP_IF_NONE:
@@ -838,6 +844,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 0;
case POP_EXCEPT:
return 0;
+ case POP_ITER:
+ return 0;
case POP_JUMP_IF_FALSE:
return 0;
case POP_JUMP_IF_NONE:
@@ -1399,6 +1407,10 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
*effect = 0;
return 0;
}
+ case INSTRUMENTED_POP_ITER: {
+ *effect = -1;
+ return 0;
+ }
case INSTRUMENTED_POP_JUMP_IF_FALSE: {
*effect = 0;
return 0;
@@ -1659,6 +1671,10 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
*effect = -1;
return 0;
}
+ case POP_ITER: {
+ *effect = -1;
+ return 0;
+ }
case POP_JUMP_IF_FALSE: {
*effect = -1;
return 0;
@@ -1921,6 +1937,7 @@ enum InstructionFormat {
#define HAS_PASSTHROUGH_FLAG (4096)
#define HAS_OPARG_AND_1_FLAG (8192)
#define HAS_ERROR_NO_POP_FLAG (16384)
+#define HAS_NO_SAVE_IP_FLAG (32768)
#define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG))
#define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG))
#define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG))
@@ -1936,6 +1953,7 @@ enum InstructionFormat {
#define OPCODE_HAS_PASSTHROUGH(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PASSTHROUGH_FLAG))
#define OPCODE_HAS_OPARG_AND_1(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_OPARG_AND_1_FLAG))
#define OPCODE_HAS_ERROR_NO_POP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_NO_POP_FLAG))
+#define OPCODE_HAS_NO_SAVE_IP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NO_SAVE_IP_FLAG))
#define OPARG_FULL 0
#define OPARG_CACHE_1 1
@@ -1948,8 +1966,8 @@ enum InstructionFormat {
struct opcode_metadata {
uint8_t valid_entry;
- int8_t instr_format;
- int16_t flags;
+ uint8_t instr_format;
+ uint16_t flags;
};
extern const struct opcode_metadata _PyOpcode_opcode_metadata[266];
@@ -2028,7 +2046,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[DICT_MERGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[DICT_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
- [END_FOR] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [END_FOR] = { true, INSTR_FMT_IX, HAS_NO_SAVE_IP_FLAG },
[END_SEND] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
[ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
@@ -2051,15 +2069,16 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[INSTRUMENTED_CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, 0 },
[INSTRUMENTED_CALL_KW] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
- [INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG },
[INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
- [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[INSTRUMENTED_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
[INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IXC, 0 },
[INSTRUMENTED_NOT_TAKEN] = { true, INSTR_FMT_IX, 0 },
+ [INSTRUMENTED_POP_ITER] = { true, INSTR_FMT_IX, 0 },
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
@@ -2119,6 +2138,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[NOP] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
[NOT_TAKEN] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
[POP_EXCEPT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
+ [POP_ITER] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
[POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
@@ -2261,7 +2281,7 @@ _PyOpcode_macro_expansion[256] = {
[DELETE_SUBSCR] = { .nuops = 1, .uops = { { _DELETE_SUBSCR, 0, 0 } } },
[DICT_MERGE] = { .nuops = 1, .uops = { { _DICT_MERGE, 0, 0 } } },
[DICT_UPDATE] = { .nuops = 1, .uops = { { _DICT_UPDATE, 0, 0 } } },
- [END_FOR] = { .nuops = 1, .uops = { { _POP_TOP, 0, 0 } } },
+ [END_FOR] = { .nuops = 1, .uops = { { _END_FOR, 0, 0 } } },
[END_SEND] = { .nuops = 1, .uops = { { _END_SEND, 0, 0 } } },
[EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { _EXIT_INIT_CHECK, 0, 0 } } },
[FORMAT_SIMPLE] = { .nuops = 1, .uops = { { _FORMAT_SIMPLE, 0, 0 } } },
@@ -2324,6 +2344,7 @@ _PyOpcode_macro_expansion[256] = {
[NOP] = { .nuops = 1, .uops = { { _NOP, 0, 0 } } },
[NOT_TAKEN] = { .nuops = 1, .uops = { { _NOP, 0, 0 } } },
[POP_EXCEPT] = { .nuops = 1, .uops = { { _POP_EXCEPT, 0, 0 } } },
+ [POP_ITER] = { .nuops = 1, .uops = { { _POP_TOP, 0, 0 } } },
[POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, 9, 1 } } },
[POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_TRUE, 9, 1 } } },
[POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_FALSE, 9, 1 } } },
@@ -2482,6 +2503,7 @@ const char *_PyOpcode_OpName[266] = {
[INSTRUMENTED_LINE] = "INSTRUMENTED_LINE",
[INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR",
[INSTRUMENTED_NOT_TAKEN] = "INSTRUMENTED_NOT_TAKEN",
+ [INSTRUMENTED_POP_ITER] = "INSTRUMENTED_POP_ITER",
[INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE",
[INSTRUMENTED_POP_JUMP_IF_NONE] = "INSTRUMENTED_POP_JUMP_IF_NONE",
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = "INSTRUMENTED_POP_JUMP_IF_NOT_NONE",
@@ -2547,6 +2569,7 @@ const char *_PyOpcode_OpName[266] = {
[NOT_TAKEN] = "NOT_TAKEN",
[POP_BLOCK] = "POP_BLOCK",
[POP_EXCEPT] = "POP_EXCEPT",
+ [POP_ITER] = "POP_ITER",
[POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
[POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE",
[POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE",
@@ -2740,6 +2763,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
[INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
[INSTRUMENTED_NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
+ [INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER,
[INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
[INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
@@ -2799,6 +2823,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[NOP] = NOP,
[NOT_TAKEN] = NOT_TAKEN,
[POP_EXCEPT] = POP_EXCEPT,
+ [POP_ITER] = POP_ITER,
[POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
[POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
[POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
@@ -2856,7 +2881,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
#endif // NEED_OPCODE_METADATA
#define EXTRA_CASES \
- case 117: \
case 118: \
case 119: \
case 120: \
@@ -2895,7 +2919,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 232: \
case 233: \
case 234: \
- case 235: \
;
struct pseudo_targets {
uint8_t as_sequence;
diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h
index 92515b4230ccb4..21690a28839565 100644
--- a/Include/internal/pycore_uop_ids.h
+++ b/Include/internal/pycore_uop_ids.h
@@ -101,6 +101,7 @@ extern "C" {
#define _DO_CALL_FUNCTION_EX 358
#define _DO_CALL_KW 359
#define _DYNAMIC_EXIT 360
+#define _END_FOR END_FOR
#define _END_SEND END_SEND
#define _ERROR_POP_N 361
#define _EXIT_INIT_CHECK EXIT_INIT_CHECK
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
index 73fc29eb78a7a4..83e578cdd76fbd 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -55,6 +55,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_STORE_FAST_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
[_POP_TOP] = HAS_PURE_FLAG,
[_PUSH_NULL] = HAS_PURE_FLAG,
+ [_END_FOR] = HAS_NO_SAVE_IP_FLAG,
[_END_SEND] = HAS_PURE_FLAG,
[_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_UNARY_NOT] = HAS_PURE_FLAG,
@@ -391,6 +392,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_DICT_MERGE] = "_DICT_MERGE",
[_DICT_UPDATE] = "_DICT_UPDATE",
[_DYNAMIC_EXIT] = "_DYNAMIC_EXIT",
+ [_END_FOR] = "_END_FOR",
[_END_SEND] = "_END_SEND",
[_ERROR_POP_N] = "_ERROR_POP_N",
[_EXIT_INIT_CHECK] = "_EXIT_INIT_CHECK",
@@ -655,6 +657,8 @@ int _PyUop_num_popped(int opcode, int oparg)
return 1;
case _PUSH_NULL:
return 0;
+ case _END_FOR:
+ return 1;
case _END_SEND:
return 2;
case _UNARY_NEGATIVE:
diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h
index 3cd189b93dd9d6..09e261fadd5544 100644
--- a/Include/opcode_ids.h
+++ b/Include/opcode_ids.h
@@ -40,93 +40,94 @@ extern "C" {
#define NOP 27
#define NOT_TAKEN 28
#define POP_EXCEPT 29
-#define POP_TOP 30
-#define PUSH_EXC_INFO 31
-#define PUSH_NULL 32
-#define RETURN_GENERATOR 33
-#define RETURN_VALUE 34
-#define SETUP_ANNOTATIONS 35
-#define STORE_SLICE 36
-#define STORE_SUBSCR 37
-#define TO_BOOL 38
-#define UNARY_INVERT 39
-#define UNARY_NEGATIVE 40
-#define UNARY_NOT 41
-#define WITH_EXCEPT_START 42
-#define BINARY_OP 43
-#define BUILD_LIST 44
-#define BUILD_MAP 45
-#define BUILD_SET 46
-#define BUILD_SLICE 47
-#define BUILD_STRING 48
-#define BUILD_TUPLE 49
-#define CALL 50
-#define CALL_FUNCTION_EX 51
-#define CALL_INTRINSIC_1 52
-#define CALL_INTRINSIC_2 53
-#define CALL_KW 54
-#define COMPARE_OP 55
-#define CONTAINS_OP 56
-#define CONVERT_VALUE 57
-#define COPY 58
-#define COPY_FREE_VARS 59
-#define DELETE_ATTR 60
-#define DELETE_DEREF 61
-#define DELETE_FAST 62
-#define DELETE_GLOBAL 63
-#define DELETE_NAME 64
-#define DICT_MERGE 65
-#define DICT_UPDATE 66
-#define EXTENDED_ARG 67
-#define FOR_ITER 68
-#define GET_AWAITABLE 69
-#define IMPORT_FROM 70
-#define IMPORT_NAME 71
-#define IS_OP 72
-#define JUMP_BACKWARD 73
-#define JUMP_BACKWARD_NO_INTERRUPT 74
-#define JUMP_FORWARD 75
-#define LIST_APPEND 76
-#define LIST_EXTEND 77
-#define LOAD_ATTR 78
-#define LOAD_COMMON_CONSTANT 79
-#define LOAD_CONST 80
-#define LOAD_DEREF 81
-#define LOAD_FAST 82
-#define LOAD_FAST_AND_CLEAR 83
-#define LOAD_FAST_CHECK 84
-#define LOAD_FAST_LOAD_FAST 85
-#define LOAD_FROM_DICT_OR_DEREF 86
-#define LOAD_FROM_DICT_OR_GLOBALS 87
-#define LOAD_GLOBAL 88
-#define LOAD_NAME 89
-#define LOAD_SMALL_INT 90
-#define LOAD_SPECIAL 91
-#define LOAD_SUPER_ATTR 92
-#define MAKE_CELL 93
-#define MAP_ADD 94
-#define MATCH_CLASS 95
-#define POP_JUMP_IF_FALSE 96
-#define POP_JUMP_IF_NONE 97
-#define POP_JUMP_IF_NOT_NONE 98
-#define POP_JUMP_IF_TRUE 99
-#define RAISE_VARARGS 100
-#define RERAISE 101
-#define SEND 102
-#define SET_ADD 103
-#define SET_FUNCTION_ATTRIBUTE 104
-#define SET_UPDATE 105
-#define STORE_ATTR 106
-#define STORE_DEREF 107
-#define STORE_FAST 108
-#define STORE_FAST_LOAD_FAST 109
-#define STORE_FAST_STORE_FAST 110
-#define STORE_GLOBAL 111
-#define STORE_NAME 112
-#define SWAP 113
-#define UNPACK_EX 114
-#define UNPACK_SEQUENCE 115
-#define YIELD_VALUE 116
+#define POP_ITER 30
+#define POP_TOP 31
+#define PUSH_EXC_INFO 32
+#define PUSH_NULL 33
+#define RETURN_GENERATOR 34
+#define RETURN_VALUE 35
+#define SETUP_ANNOTATIONS 36
+#define STORE_SLICE 37
+#define STORE_SUBSCR 38
+#define TO_BOOL 39
+#define UNARY_INVERT 40
+#define UNARY_NEGATIVE 41
+#define UNARY_NOT 42
+#define WITH_EXCEPT_START 43
+#define BINARY_OP 44
+#define BUILD_LIST 45
+#define BUILD_MAP 46
+#define BUILD_SET 47
+#define BUILD_SLICE 48
+#define BUILD_STRING 49
+#define BUILD_TUPLE 50
+#define CALL 51
+#define CALL_FUNCTION_EX 52
+#define CALL_INTRINSIC_1 53
+#define CALL_INTRINSIC_2 54
+#define CALL_KW 55
+#define COMPARE_OP 56
+#define CONTAINS_OP 57
+#define CONVERT_VALUE 58
+#define COPY 59
+#define COPY_FREE_VARS 60
+#define DELETE_ATTR 61
+#define DELETE_DEREF 62
+#define DELETE_FAST 63
+#define DELETE_GLOBAL 64
+#define DELETE_NAME 65
+#define DICT_MERGE 66
+#define DICT_UPDATE 67
+#define EXTENDED_ARG 68
+#define FOR_ITER 69
+#define GET_AWAITABLE 70
+#define IMPORT_FROM 71
+#define IMPORT_NAME 72
+#define IS_OP 73
+#define JUMP_BACKWARD 74
+#define JUMP_BACKWARD_NO_INTERRUPT 75
+#define JUMP_FORWARD 76
+#define LIST_APPEND 77
+#define LIST_EXTEND 78
+#define LOAD_ATTR 79
+#define LOAD_COMMON_CONSTANT 80
+#define LOAD_CONST 81
+#define LOAD_DEREF 82
+#define LOAD_FAST 83
+#define LOAD_FAST_AND_CLEAR 84
+#define LOAD_FAST_CHECK 85
+#define LOAD_FAST_LOAD_FAST 86
+#define LOAD_FROM_DICT_OR_DEREF 87
+#define LOAD_FROM_DICT_OR_GLOBALS 88
+#define LOAD_GLOBAL 89
+#define LOAD_NAME 90
+#define LOAD_SMALL_INT 91
+#define LOAD_SPECIAL 92
+#define LOAD_SUPER_ATTR 93
+#define MAKE_CELL 94
+#define MAP_ADD 95
+#define MATCH_CLASS 96
+#define POP_JUMP_IF_FALSE 97
+#define POP_JUMP_IF_NONE 98
+#define POP_JUMP_IF_NOT_NONE 99
+#define POP_JUMP_IF_TRUE 100
+#define RAISE_VARARGS 101
+#define RERAISE 102
+#define SEND 103
+#define SET_ADD 104
+#define SET_FUNCTION_ATTRIBUTE 105
+#define SET_UPDATE 106
+#define STORE_ATTR 107
+#define STORE_DEREF 108
+#define STORE_FAST 109
+#define STORE_FAST_LOAD_FAST 110
+#define STORE_FAST_STORE_FAST 111
+#define STORE_GLOBAL 112
+#define STORE_NAME 113
+#define SWAP 114
+#define UNPACK_EX 115
+#define UNPACK_SEQUENCE 116
+#define YIELD_VALUE 117
#define RESUME 149
#define BINARY_OP_ADD_FLOAT 150
#define BINARY_OP_ADD_INT 151
@@ -206,7 +207,8 @@ extern "C" {
#define UNPACK_SEQUENCE_LIST 225
#define UNPACK_SEQUENCE_TUPLE 226
#define UNPACK_SEQUENCE_TWO_TUPLE 227
-#define INSTRUMENTED_END_FOR 236
+#define INSTRUMENTED_END_FOR 235
+#define INSTRUMENTED_POP_ITER 236
#define INSTRUMENTED_END_SEND 237
#define INSTRUMENTED_LOAD_SUPER_ATTR 238
#define INSTRUMENTED_FOR_ITER 239
@@ -237,9 +239,9 @@ extern "C" {
#define SETUP_WITH 264
#define STORE_FAST_MAYBE_NULL 265
-#define HAVE_ARGUMENT 42
+#define HAVE_ARGUMENT 43
#define MIN_SPECIALIZED_OPCODE 150
-#define MIN_INSTRUMENTED_OPCODE 236
+#define MIN_INSTRUMENTED_OPCODE 235
#ifdef __cplusplus
}
diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py
index dada2cb5fa033f..64ee56fd10556f 100644
--- a/Lib/_opcode_metadata.py
+++ b/Lib/_opcode_metadata.py
@@ -233,94 +233,96 @@
'NOP': 27,
'NOT_TAKEN': 28,
'POP_EXCEPT': 29,
- 'POP_TOP': 30,
- 'PUSH_EXC_INFO': 31,
- 'PUSH_NULL': 32,
- 'RETURN_GENERATOR': 33,
- 'RETURN_VALUE': 34,
- 'SETUP_ANNOTATIONS': 35,
- 'STORE_SLICE': 36,
- 'STORE_SUBSCR': 37,
- 'TO_BOOL': 38,
- 'UNARY_INVERT': 39,
- 'UNARY_NEGATIVE': 40,
- 'UNARY_NOT': 41,
- 'WITH_EXCEPT_START': 42,
- 'BINARY_OP': 43,
- 'BUILD_LIST': 44,
- 'BUILD_MAP': 45,
- 'BUILD_SET': 46,
- 'BUILD_SLICE': 47,
- 'BUILD_STRING': 48,
- 'BUILD_TUPLE': 49,
- 'CALL': 50,
- 'CALL_FUNCTION_EX': 51,
- 'CALL_INTRINSIC_1': 52,
- 'CALL_INTRINSIC_2': 53,
- 'CALL_KW': 54,
- 'COMPARE_OP': 55,
- 'CONTAINS_OP': 56,
- 'CONVERT_VALUE': 57,
- 'COPY': 58,
- 'COPY_FREE_VARS': 59,
- 'DELETE_ATTR': 60,
- 'DELETE_DEREF': 61,
- 'DELETE_FAST': 62,
- 'DELETE_GLOBAL': 63,
- 'DELETE_NAME': 64,
- 'DICT_MERGE': 65,
- 'DICT_UPDATE': 66,
- 'EXTENDED_ARG': 67,
- 'FOR_ITER': 68,
- 'GET_AWAITABLE': 69,
- 'IMPORT_FROM': 70,
- 'IMPORT_NAME': 71,
- 'IS_OP': 72,
- 'JUMP_BACKWARD': 73,
- 'JUMP_BACKWARD_NO_INTERRUPT': 74,
- 'JUMP_FORWARD': 75,
- 'LIST_APPEND': 76,
- 'LIST_EXTEND': 77,
- 'LOAD_ATTR': 78,
- 'LOAD_COMMON_CONSTANT': 79,
- 'LOAD_CONST': 80,
- 'LOAD_DEREF': 81,
- 'LOAD_FAST': 82,
- 'LOAD_FAST_AND_CLEAR': 83,
- 'LOAD_FAST_CHECK': 84,
- 'LOAD_FAST_LOAD_FAST': 85,
- 'LOAD_FROM_DICT_OR_DEREF': 86,
- 'LOAD_FROM_DICT_OR_GLOBALS': 87,
- 'LOAD_GLOBAL': 88,
- 'LOAD_NAME': 89,
- 'LOAD_SMALL_INT': 90,
- 'LOAD_SPECIAL': 91,
- 'LOAD_SUPER_ATTR': 92,
- 'MAKE_CELL': 93,
- 'MAP_ADD': 94,
- 'MATCH_CLASS': 95,
- 'POP_JUMP_IF_FALSE': 96,
- 'POP_JUMP_IF_NONE': 97,
- 'POP_JUMP_IF_NOT_NONE': 98,
- 'POP_JUMP_IF_TRUE': 99,
- 'RAISE_VARARGS': 100,
- 'RERAISE': 101,
- 'SEND': 102,
- 'SET_ADD': 103,
- 'SET_FUNCTION_ATTRIBUTE': 104,
- 'SET_UPDATE': 105,
- 'STORE_ATTR': 106,
- 'STORE_DEREF': 107,
- 'STORE_FAST': 108,
- 'STORE_FAST_LOAD_FAST': 109,
- 'STORE_FAST_STORE_FAST': 110,
- 'STORE_GLOBAL': 111,
- 'STORE_NAME': 112,
- 'SWAP': 113,
- 'UNPACK_EX': 114,
- 'UNPACK_SEQUENCE': 115,
- 'YIELD_VALUE': 116,
- 'INSTRUMENTED_END_FOR': 236,
+ 'POP_ITER': 30,
+ 'POP_TOP': 31,
+ 'PUSH_EXC_INFO': 32,
+ 'PUSH_NULL': 33,
+ 'RETURN_GENERATOR': 34,
+ 'RETURN_VALUE': 35,
+ 'SETUP_ANNOTATIONS': 36,
+ 'STORE_SLICE': 37,
+ 'STORE_SUBSCR': 38,
+ 'TO_BOOL': 39,
+ 'UNARY_INVERT': 40,
+ 'UNARY_NEGATIVE': 41,
+ 'UNARY_NOT': 42,
+ 'WITH_EXCEPT_START': 43,
+ 'BINARY_OP': 44,
+ 'BUILD_LIST': 45,
+ 'BUILD_MAP': 46,
+ 'BUILD_SET': 47,
+ 'BUILD_SLICE': 48,
+ 'BUILD_STRING': 49,
+ 'BUILD_TUPLE': 50,
+ 'CALL': 51,
+ 'CALL_FUNCTION_EX': 52,
+ 'CALL_INTRINSIC_1': 53,
+ 'CALL_INTRINSIC_2': 54,
+ 'CALL_KW': 55,
+ 'COMPARE_OP': 56,
+ 'CONTAINS_OP': 57,
+ 'CONVERT_VALUE': 58,
+ 'COPY': 59,
+ 'COPY_FREE_VARS': 60,
+ 'DELETE_ATTR': 61,
+ 'DELETE_DEREF': 62,
+ 'DELETE_FAST': 63,
+ 'DELETE_GLOBAL': 64,
+ 'DELETE_NAME': 65,
+ 'DICT_MERGE': 66,
+ 'DICT_UPDATE': 67,
+ 'EXTENDED_ARG': 68,
+ 'FOR_ITER': 69,
+ 'GET_AWAITABLE': 70,
+ 'IMPORT_FROM': 71,
+ 'IMPORT_NAME': 72,
+ 'IS_OP': 73,
+ 'JUMP_BACKWARD': 74,
+ 'JUMP_BACKWARD_NO_INTERRUPT': 75,
+ 'JUMP_FORWARD': 76,
+ 'LIST_APPEND': 77,
+ 'LIST_EXTEND': 78,
+ 'LOAD_ATTR': 79,
+ 'LOAD_COMMON_CONSTANT': 80,
+ 'LOAD_CONST': 81,
+ 'LOAD_DEREF': 82,
+ 'LOAD_FAST': 83,
+ 'LOAD_FAST_AND_CLEAR': 84,
+ 'LOAD_FAST_CHECK': 85,
+ 'LOAD_FAST_LOAD_FAST': 86,
+ 'LOAD_FROM_DICT_OR_DEREF': 87,
+ 'LOAD_FROM_DICT_OR_GLOBALS': 88,
+ 'LOAD_GLOBAL': 89,
+ 'LOAD_NAME': 90,
+ 'LOAD_SMALL_INT': 91,
+ 'LOAD_SPECIAL': 92,
+ 'LOAD_SUPER_ATTR': 93,
+ 'MAKE_CELL': 94,
+ 'MAP_ADD': 95,
+ 'MATCH_CLASS': 96,
+ 'POP_JUMP_IF_FALSE': 97,
+ 'POP_JUMP_IF_NONE': 98,
+ 'POP_JUMP_IF_NOT_NONE': 99,
+ 'POP_JUMP_IF_TRUE': 100,
+ 'RAISE_VARARGS': 101,
+ 'RERAISE': 102,
+ 'SEND': 103,
+ 'SET_ADD': 104,
+ 'SET_FUNCTION_ATTRIBUTE': 105,
+ 'SET_UPDATE': 106,
+ 'STORE_ATTR': 107,
+ 'STORE_DEREF': 108,
+ 'STORE_FAST': 109,
+ 'STORE_FAST_LOAD_FAST': 110,
+ 'STORE_FAST_STORE_FAST': 111,
+ 'STORE_GLOBAL': 112,
+ 'STORE_NAME': 113,
+ 'SWAP': 114,
+ 'UNPACK_EX': 115,
+ 'UNPACK_SEQUENCE': 116,
+ 'YIELD_VALUE': 117,
+ 'INSTRUMENTED_END_FOR': 235,
+ 'INSTRUMENTED_POP_ITER': 236,
'INSTRUMENTED_END_SEND': 237,
'INSTRUMENTED_LOAD_SUPER_ATTR': 238,
'INSTRUMENTED_FOR_ITER': 239,
@@ -350,5 +352,5 @@
'STORE_FAST_MAYBE_NULL': 265,
}
-HAVE_ARGUMENT = 42
-MIN_INSTRUMENTED_OPCODE = 236
+HAVE_ARGUMENT = 43
+MIN_INSTRUMENTED_OPCODE = 235
diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py
index 2a1b26e8a1ffd1..7ffa4eb8639add 100644
--- a/Lib/test/test_code.py
+++ b/Lib/test/test_code.py
@@ -215,6 +215,8 @@
from test.support import threading_helper, import_helper
from test.support.bytecode_helper import instructions_with_positions
from opcode import opmap, opname
+from _testcapi import code_offset_to_line
+
COPY_FREE_VARS = opmap['COPY_FREE_VARS']
@@ -896,6 +898,44 @@ async def async_func():
rc, out, err = assert_python_ok('-OO', '-c', code)
+ def test_co_branches(self):
+
+ def get_line_branches(func):
+ code = func.__code__
+ base = code.co_firstlineno
+ return [
+ (
+ code_offset_to_line(code, src) - base,
+ code_offset_to_line(code, left) - base,
+ code_offset_to_line(code, right) - base
+ ) for (src, left, right) in
+ code.co_branches()
+ ]
+
+ def simple(x):
+ if x:
+ A
+ else:
+ B
+
+ self.assertEqual(
+ get_line_branches(simple),
+ [(1,2,4)])
+
+ def with_extended_args(x):
+ if x:
+ A.x; A.x; A.x; A.x; A.x; A.x;
+ A.x; A.x; A.x; A.x; A.x; A.x;
+ A.x; A.x; A.x; A.x; A.x; A.x;
+ A.x; A.x; A.x; A.x; A.x; A.x;
+ A.x; A.x; A.x; A.x; A.x; A.x;
+ else:
+ B
+
+ self.assertEqual(
+ get_line_branches(with_extended_args),
+ [(1,2,8)])
+
if check_impl_detail(cpython=True) and ctypes is not None:
py = ctypes.pythonapi
freefunc = ctypes.CFUNCTYPE(None,ctypes.c_voidp)
diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py
index f8c4fc14c91ebe..5655e1b9cf196a 100644
--- a/Lib/test/test_compiler_codegen.py
+++ b/Lib/test/test_compiler_codegen.py
@@ -50,7 +50,6 @@ def test_for_loop(self):
('GET_ITER', None, 1),
loop_lbl := self.Label(),
('FOR_ITER', exit_lbl := self.Label(), 1),
- ('NOT_TAKEN', None, 1),
('NOP', None, 1, 1),
('STORE_NAME', 1, 1),
('LOAD_NAME', 2, 2),
@@ -61,7 +60,7 @@ def test_for_loop(self):
('JUMP', loop_lbl),
exit_lbl,
('END_FOR', None),
- ('POP_TOP', None),
+ ('POP_ITER', None),
('LOAD_CONST', 0),
('RETURN_VALUE', None),
]
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index 955a3e4cb9e4f7..e733a673d003e7 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -175,14 +175,13 @@ def bug708901():
%3d CALL 2
GET_ITER
- L1: FOR_ITER 4 (to L2)
- NOT_TAKEN
+ L1: FOR_ITER 3 (to L2)
STORE_FAST 0 (res)
-%3d JUMP_BACKWARD 6 (to L1)
+%3d JUMP_BACKWARD 5 (to L1)
%3d L2: END_FOR
- POP_TOP
+ POP_ITER
LOAD_CONST 0 (None)
RETURN_VALUE
""" % (bug708901.__code__.co_firstlineno,
@@ -844,8 +843,7 @@ def foo(x):
L1: RESUME 0
LOAD_FAST 0 (.0)
GET_ITER
- L2: FOR_ITER 11 (to L3)
- NOT_TAKEN
+ L2: FOR_ITER 10 (to L3)
STORE_FAST 1 (z)
LOAD_DEREF 2 (x)
LOAD_FAST 1 (z)
@@ -853,9 +851,9 @@ def foo(x):
YIELD_VALUE 0
RESUME 5
POP_TOP
- JUMP_BACKWARD 13 (to L2)
+ JUMP_BACKWARD 12 (to L2)
L3: END_FOR
- POP_TOP
+ POP_ITER
LOAD_CONST 0 (None)
RETURN_VALUE
@@ -899,18 +897,17 @@ def loop_test():
LOAD_SMALL_INT 3
BINARY_OP 5 (*)
GET_ITER
- L1: FOR_ITER_LIST 15 (to L2)
- NOT_TAKEN
+ L1: FOR_ITER_LIST 14 (to L2)
STORE_FAST 0 (i)
%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL)
LOAD_FAST 0 (i)
CALL_PY_GENERAL 1
POP_TOP
- JUMP_BACKWARD 17 (to L1)
+ JUMP_BACKWARD 16 (to L1)
%3d L2: END_FOR
- POP_TOP
+ POP_ITER
LOAD_CONST_IMMORTAL 1 (None)
RETURN_VALUE
""" % (loop_test.__code__.co_firstlineno,
@@ -1706,214 +1703,213 @@ def _prepare_test_cases():
Instruction = dis.Instruction
expected_opinfo_outer = [
- Instruction(opname='MAKE_CELL', opcode=93, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='MAKE_CELL', opcode=93, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='BUILD_TUPLE', opcode=49, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='BUILD_TUPLE', opcode=50, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
Instruction(opname='MAKE_FUNCTION', opcode=23, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=104, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=104, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='STORE_FAST', opcode=108, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=1, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=1, argval=1, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='BUILD_LIST', opcode=44, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='BUILD_MAP', opcode=45, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=2, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=34, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='STORE_FAST', opcode=109, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='BUILD_LIST', opcode=45, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='BUILD_MAP', opcode=46, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
]
expected_opinfo_f = [
- Instruction(opname='COPY_FREE_VARS', opcode=59, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='MAKE_CELL', opcode=93, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='MAKE_CELL', opcode=93, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY_FREE_VARS', opcode=60, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=1, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='BUILD_TUPLE', opcode=49, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='BUILD_TUPLE', opcode=50, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
Instruction(opname='MAKE_FUNCTION', opcode=23, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=104, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=104, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='STORE_FAST', opcode=108, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=34, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=105, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='STORE_FAST', opcode=109, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None),
]
expected_opinfo_inner = [
- Instruction(opname='COPY_FREE_VARS', opcode=59, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY_FREE_VARS', opcode=60, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_DEREF', opcode=81, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=85, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=34, arg=None, argval=None, argrepr='', offset=36, start_offset=36, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_DEREF', opcode=82, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=86, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=36, start_offset=36, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
]
expected_opinfo_jumpy = [
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=10, argval=10, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=10, argval=10, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
Instruction(opname='GET_ITER', opcode=16, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='FOR_ITER', opcode=68, arg=34, argval=96, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='STORE_FAST', opcode=108, arg=0, argval='i', argrepr='i', offset=30, start_offset=30, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=32, start_offset=32, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=52, start_offset=52, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=54, start_offset=54, starts_line=True, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=4, argval=4, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=55, arg=18, argval='<', argrepr='bool(<)', offset=58, start_offset=58, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=96, arg=3, argval=72, argrepr='to L2', offset=62, start_offset=62, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=66, start_offset=66, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=73, arg=24, argval=24, argrepr='to L1', offset=68, start_offset=68, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=72, start_offset=72, starts_line=True, line_number=7, label=2, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=6, argval=6, argrepr='', offset=74, start_offset=74, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=55, arg=148, argval='>', argrepr='bool(>)', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=99, arg=3, argval=90, argrepr='to L3', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=73, arg=33, argval=24, argrepr='to L1', offset=86, start_offset=86, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=90, start_offset=90, starts_line=True, line_number=None, label=3, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_FORWARD', opcode=75, arg=13, argval=122, argrepr='to L5', offset=94, start_offset=94, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
- Instruction(opname='END_FOR', opcode=9, arg=None, argval=None, argrepr='', offset=96, start_offset=96, starts_line=True, line_number=3, label=4, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=98, start_offset=98, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=100, start_offset=100, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=112, start_offset=112, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=120, start_offset=120, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST_CHECK', opcode=84, arg=0, argval='i', argrepr='i', offset=122, start_offset=122, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
- Instruction(opname='TO_BOOL', opcode=38, arg=None, argval=None, argrepr='', offset=124, start_offset=124, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=96, arg=37, argval=210, argrepr='to L8', offset=132, start_offset=132, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=136, start_offset=136, starts_line=False, line_number=11, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=138, start_offset=138, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=148, start_offset=148, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=150, start_offset=150, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=158, start_offset=158, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=160, start_offset=160, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=1, argval=1, argrepr='', offset=162, start_offset=162, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='BINARY_OP', opcode=43, arg=23, argval=23, argrepr='-=', offset=164, start_offset=164, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='STORE_FAST', opcode=108, arg=0, argval='i', argrepr='i', offset=168, start_offset=168, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=170, start_offset=170, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=6, argval=6, argrepr='', offset=172, start_offset=172, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=55, arg=148, argval='>', argrepr='bool(>)', offset=174, start_offset=174, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=96, arg=3, argval=188, argrepr='to L6', offset=178, start_offset=178, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=182, start_offset=182, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=73, arg=33, argval=122, argrepr='to L5', offset=184, start_offset=184, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=4, argval=4, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
- Instruction(opname='COMPARE_OP', opcode=55, arg=18, argval='<', argrepr='bool(<)', offset=192, start_offset=192, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=99, arg=3, argval=206, argrepr='to L7', offset=196, start_offset=196, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=200, start_offset=200, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD', opcode=73, arg=42, argval=122, argrepr='to L5', offset=202, start_offset=202, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=206, start_offset=206, starts_line=True, line_number=None, label=7, positions=None, cache_info=None),
- Instruction(opname='JUMP_FORWARD', opcode=75, arg=11, argval=232, argrepr='to L9', offset=208, start_offset=208, starts_line=True, line_number=17, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=210, start_offset=210, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=80, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=220, start_offset=220, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=222, start_offset=222, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=230, start_offset=230, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
- Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=232, start_offset=232, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=1, argval=1, argrepr='', offset=234, start_offset=234, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SMALL_INT', opcode=90, arg=0, argval=0, argrepr='', offset=236, start_offset=236, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='BINARY_OP', opcode=43, arg=11, argval=11, argrepr='/', offset=238, start_offset=238, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='i', argrepr='i', offset=244, start_offset=244, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=58, arg=1, argval=1, argrepr='', offset=246, start_offset=246, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=91, arg=1, argval=1, argrepr='__exit__', offset=248, start_offset=248, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='SWAP', opcode=113, arg=2, argval=2, argrepr='', offset=250, start_offset=250, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='SWAP', opcode=113, arg=3, argval=3, argrepr='', offset=252, start_offset=252, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=91, arg=0, argval=0, argrepr='__enter__', offset=254, start_offset=254, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=0, argval=0, argrepr='', offset=256, start_offset=256, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='STORE_FAST', opcode=108, arg=1, argval='dodgy', argrepr='dodgy', offset=264, start_offset=264, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=266, start_offset=266, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=80, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=276, start_offset=276, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=278, start_offset=278, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=286, start_offset=286, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=None, argrepr='None', offset=288, start_offset=288, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=None, argrepr='None', offset=290, start_offset=290, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=None, argrepr='None', offset=292, start_offset=292, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=3, argval=3, argrepr='', offset=294, start_offset=294, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=302, start_offset=302, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=304, start_offset=304, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=80, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=314, start_offset=314, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=316, start_offset=316, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=3, argval=None, argrepr='None', offset=326, start_offset=326, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='RETURN_VALUE', opcode=34, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=31, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='WITH_EXCEPT_START', opcode=42, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='TO_BOOL', opcode=38, arg=None, argval=None, argrepr='', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=99, arg=2, argval=350, argrepr='to L11', offset=342, start_offset=342, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=101, arg=2, argval=2, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=350, start_offset=350, starts_line=False, line_number=25, label=11, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=352, start_offset=352, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=354, start_offset=354, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=358, start_offset=358, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=74, arg=29, argval=304, argrepr='to L10', offset=360, start_offset=360, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=58, arg=3, argval=3, argrepr='', offset=362, start_offset=362, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=364, start_offset=364, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=101, arg=1, argval=1, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=31, arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=370, start_offset=370, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='CHECK_EXC_MATCH', opcode=5, arg=None, argval=None, argrepr='', offset=380, start_offset=380, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=96, arg=15, argval=416, argrepr='to L12', offset=382, start_offset=382, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
- Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=388, start_offset=388, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=390, start_offset=390, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=80, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=400, start_offset=400, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=402, start_offset=402, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=410, start_offset=410, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=412, start_offset=412, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=74, arg=56, argval=304, argrepr='to L10', offset=414, start_offset=414, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=101, arg=0, argval=0, argrepr='', offset=416, start_offset=416, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=58, arg=3, argval=3, argrepr='', offset=418, start_offset=418, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=420, start_offset=420, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=101, arg=1, argval=1, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=31, arg=None, argval=None, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=426, start_offset=426, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
- Instruction(opname='LOAD_CONST', opcode=80, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=436, start_offset=436, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='CALL', opcode=50, arg=1, argval=1, argrepr='', offset=438, start_offset=438, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
- Instruction(opname='POP_TOP', opcode=30, arg=None, argval=None, argrepr='', offset=446, start_offset=446, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=101, arg=0, argval=0, argrepr='', offset=448, start_offset=448, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
- Instruction(opname='COPY', opcode=58, arg=3, argval=3, argrepr='', offset=450, start_offset=450, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=452, start_offset=452, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
- Instruction(opname='RERAISE', opcode=101, arg=1, argval=1, argrepr='', offset=454, start_offset=454, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='FOR_ITER', opcode=69, arg=33, argval=94, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=4, argval=4, argrepr='', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=3, argval=70, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=64, start_offset=64, starts_line=False, line_number=5, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=23, argval=24, argrepr='to L1', offset=66, start_offset=66, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=70, start_offset=70, starts_line=True, line_number=7, label=2, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=6, argval=6, argrepr='', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=74, start_offset=74, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=88, argrepr='to L3', offset=78, start_offset=78, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=82, start_offset=82, starts_line=False, line_number=7, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=32, argval=24, argrepr='to L1', offset=84, start_offset=84, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=None, label=3, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=90, start_offset=90, starts_line=True, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_FORWARD', opcode=76, arg=13, argval=120, argrepr='to L5', offset=92, start_offset=92, starts_line=False, line_number=8, label=None, positions=None, cache_info=None),
+ Instruction(opname='END_FOR', opcode=9, arg=None, argval=None, argrepr='', offset=94, start_offset=94, starts_line=True, line_number=3, label=4, positions=None, cache_info=None),
+ Instruction(opname='POP_ITER', opcode=30, arg=None, argval=None, argrepr='', offset=96, start_offset=96, starts_line=False, line_number=3, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=98, start_offset=98, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=108, start_offset=108, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=118, start_offset=118, starts_line=False, line_number=10, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST_CHECK', opcode=85, arg=0, argval='i', argrepr='i', offset=120, start_offset=120, starts_line=True, line_number=11, label=5, positions=None, cache_info=None),
+ Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=37, argval=208, argrepr='to L8', offset=130, start_offset=130, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=134, start_offset=134, starts_line=False, line_number=11, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=136, start_offset=136, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=146, start_offset=146, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=148, start_offset=148, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=156, start_offset=156, starts_line=False, line_number=12, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=160, start_offset=160, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='BINARY_OP', opcode=44, arg=23, argval=23, argrepr='-=', offset=162, start_offset=162, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=109, arg=0, argval='i', argrepr='i', offset=166, start_offset=166, starts_line=False, line_number=13, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=168, start_offset=168, starts_line=True, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=6, argval=6, argrepr='', offset=170, start_offset=170, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=148, argval='>', argrepr='bool(>)', offset=172, start_offset=172, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=3, argval=186, argrepr='to L6', offset=176, start_offset=176, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=180, start_offset=180, starts_line=False, line_number=14, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=33, argval=120, argrepr='to L5', offset=182, start_offset=182, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=186, start_offset=186, starts_line=True, line_number=16, label=6, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=4, argval=4, argrepr='', offset=188, start_offset=188, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
+ Instruction(opname='COMPARE_OP', opcode=56, arg=18, argval='<', argrepr='bool(<)', offset=190, start_offset=190, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=3, argval=204, argrepr='to L7', offset=194, start_offset=194, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=198, start_offset=198, starts_line=False, line_number=16, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=74, arg=42, argval=120, argrepr='to L5', offset=200, start_offset=200, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=204, start_offset=204, starts_line=True, line_number=None, label=7, positions=None, cache_info=None),
+ Instruction(opname='JUMP_FORWARD', opcode=76, arg=11, argval=230, argrepr='to L9', offset=206, start_offset=206, starts_line=True, line_number=17, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=208, start_offset=208, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=218, start_offset=218, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=220, start_offset=220, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=228, start_offset=228, starts_line=False, line_number=19, label=None, positions=None, cache_info=None),
+ Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=230, start_offset=230, starts_line=True, line_number=20, label=9, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=1, argval=1, argrepr='', offset=232, start_offset=232, starts_line=True, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SMALL_INT', opcode=91, arg=0, argval=0, argrepr='', offset=234, start_offset=234, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='BINARY_OP', opcode=44, arg=11, argval=11, argrepr='/', offset=236, start_offset=236, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=240, start_offset=240, starts_line=False, line_number=21, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i', offset=242, start_offset=242, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=1, argval=1, argrepr='', offset=244, start_offset=244, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=92, arg=1, argval=1, argrepr='__exit__', offset=246, start_offset=246, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='SWAP', opcode=114, arg=2, argval=2, argrepr='', offset=248, start_offset=248, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='SWAP', opcode=114, arg=3, argval=3, argrepr='', offset=250, start_offset=250, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=92, arg=0, argval=0, argrepr='__enter__', offset=252, start_offset=252, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=0, argval=0, argrepr='', offset=254, start_offset=254, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='STORE_FAST', opcode=109, arg=1, argval='dodgy', argrepr='dodgy', offset=262, start_offset=262, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=264, start_offset=264, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=274, start_offset=274, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=276, start_offset=276, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=284, start_offset=284, starts_line=False, line_number=26, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=286, start_offset=286, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=288, start_offset=288, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=290, start_offset=290, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=3, argval=3, argrepr='', offset=292, start_offset=292, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=300, start_offset=300, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=302, start_offset=302, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=312, start_offset=312, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=314, start_offset=314, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=322, start_offset=322, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=3, argval=None, argrepr='None', offset=324, start_offset=324, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=True, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='WITH_EXCEPT_START', opcode=43, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='TO_BOOL', opcode=39, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=348, argrepr='to L11', offset=340, start_offset=340, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=25, label=11, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=350, start_offset=350, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=352, start_offset=352, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=354, start_offset=354, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=29, argval=302, argrepr='to L10', offset=358, start_offset=358, starts_line=False, line_number=25, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=360, start_offset=360, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=364, start_offset=364, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=368, start_offset=368, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='CHECK_EXC_MATCH', opcode=5, arg=None, argval=None, argrepr='', offset=378, start_offset=378, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=414, argrepr='to L12', offset=380, start_offset=380, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]),
+ Instruction(opname='NOT_TAKEN', opcode=28, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=22, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=388, start_offset=388, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=398, start_offset=398, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=408, start_offset=408, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=410, start_offset=410, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=75, arg=56, argval=302, argrepr='to L10', offset=412, start_offset=412, starts_line=False, line_number=23, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=414, start_offset=414, starts_line=True, line_number=22, label=12, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=416, start_offset=416, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=418, start_offset=418, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=420, start_offset=420, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print', argrepr='print + NULL', offset=424, start_offset=424, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=434, start_offset=434, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='CALL', opcode=51, arg=1, argval=1, argrepr='', offset=436, start_offset=436, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]),
+ Instruction(opname='POP_TOP', opcode=31, arg=None, argval=None, argrepr='', offset=444, start_offset=444, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=446, start_offset=446, starts_line=False, line_number=28, label=None, positions=None, cache_info=None),
+ Instruction(opname='COPY', opcode=59, arg=3, argval=3, argrepr='', offset=448, start_offset=448, starts_line=True, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='POP_EXCEPT', opcode=29, arg=None, argval=None, argrepr='', offset=450, start_offset=450, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
+ Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=452, start_offset=452, starts_line=False, line_number=None, label=None, positions=None, cache_info=None),
]
# One last piece of inspect fodder to check the default line number handling
def simple(): pass
expected_opinfo_simple = [
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, label=None, positions=None),
- Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
- Instruction(opname='RETURN_VALUE', opcode=34, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
+ Instruction(opname='LOAD_CONST', opcode=81, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
+ Instruction(opname='RETURN_VALUE', opcode=35, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None),
]
diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py
index 32b3a6ac049e28..43e3e56639db62 100644
--- a/Lib/test/test_monitoring.py
+++ b/Lib/test/test_monitoring.py
@@ -1589,11 +1589,11 @@ def whilefunc(n=0):
('branch right', 'whilefunc', 1, 3)])
self.check_events(func, recorders = BRANCH_OFFSET_RECORDERS, expected = [
- ('branch left', 'func', 28, 34),
- ('branch right', 'func', 46, 60),
- ('branch left', 'func', 28, 34),
- ('branch left', 'func', 46, 52),
- ('branch right', 'func', 28, 72)])
+ ('branch left', 'func', 28, 32),
+ ('branch right', 'func', 44, 58),
+ ('branch left', 'func', 28, 32),
+ ('branch left', 'func', 44, 50),
+ ('branch right', 'func', 28, 70)])
def test_except_star(self):
@@ -1658,6 +1658,88 @@ def foo(n=0):
exit_loop])
+class TestBranchConsistency(MonitoringTestBase, unittest.TestCase):
+
+ def check_branches(self, func, tool=TEST_TOOL, recorders=BRANCH_OFFSET_RECORDERS):
+ try:
+ self.assertEqual(sys.monitoring._all_events(), {})
+ event_list = []
+ all_events = 0
+ for recorder in recorders:
+ ev = recorder.event_type
+ sys.monitoring.register_callback(tool, ev, recorder(event_list))
+ all_events |= ev
+ sys.monitoring.set_local_events(tool, func.__code__, all_events)
+ func()
+ sys.monitoring.set_local_events(tool, func.__code__, 0)
+ for recorder in recorders:
+ sys.monitoring.register_callback(tool, recorder.event_type, None)
+ lefts = set()
+ rights = set()
+ for (src, left, right) in func.__code__.co_branches():
+ lefts.add((src, left))
+ rights.add((src, right))
+ for event in event_list:
+ way, _, src, dest = event
+ if "left" in way:
+ self.assertIn((src, dest), lefts)
+ else:
+ self.assertIn("right", way)
+ self.assertIn((src, dest), rights)
+ finally:
+ sys.monitoring.set_local_events(tool, func.__code__, 0)
+ for recorder in recorders:
+ sys.monitoring.register_callback(tool, recorder.event_type, None)
+
+ def test_simple(self):
+
+ def func():
+ x = 1
+ for a in range(2):
+ if a:
+ x = 4
+ else:
+ x = 6
+ 7
+
+ self.check_branches(func)
+
+ def whilefunc(n=0):
+ while n < 3:
+ n += 1 # line 2
+ 3
+
+ self.check_branches(whilefunc)
+
+ def test_except_star(self):
+
+ class Foo:
+ def meth(self):
+ pass
+
+ def func():
+ try:
+ try:
+ raise KeyError
+ except* Exception as e:
+ f = Foo(); f.meth()
+ except KeyError:
+ pass
+
+
+ self.check_branches(func)
+
+ def test4(self):
+
+ def foo(n=0):
+ while n<4:
+ pass
+ n += 1
+ return None
+
+ self.check_branches(foo)
+
+
class TestLoadSuperAttr(CheckEvents):
RECORDERS = CallRecorder, LineRecorder, CRaiseRecorder, CReturnRecorder
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index cd9014118f2d7f..a0a1f8af6710a3 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -3415,6 +3415,26 @@ test_atexit(PyObject *self, PyObject *Py_UNUSED(args))
Py_RETURN_NONE;
}
+static PyObject*
+code_offset_to_line(PyObject* self, PyObject* const* args, Py_ssize_t nargsf)
+{
+ Py_ssize_t nargs = _PyVectorcall_NARGS(nargsf);
+ if (nargs != 2) {
+ PyErr_SetString(PyExc_TypeError, "code_offset_to_line takes 2 arguments");
+ return NULL;
+ }
+ int offset;
+ if (PyLong_AsInt32(args[1], &offset) < 0) {
+ return NULL;
+ }
+ PyCodeObject *code = (PyCodeObject *)args[0];
+ if (!PyCode_Check(code)) {
+ PyErr_SetString(PyExc_TypeError, "first arg must be a code object");
+ return NULL;
+ }
+ return PyLong_FromInt32(PyCode_Addr2Line(code, offset));
+}
+
static PyMethodDef TestMethods[] = {
{"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS},
@@ -3557,6 +3577,7 @@ static PyMethodDef TestMethods[] = {
{"finalize_thread_hang", finalize_thread_hang, METH_O, NULL},
{"type_freeze", type_freeze, METH_VARARGS},
{"test_atexit", test_atexit, METH_NOARGS},
+ {"code_offset_to_line", _PyCFunction_CAST(code_offset_to_line), METH_FASTCALL},
{NULL, NULL} /* sentinel */
};
diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h
index a0007830e8cbc0..4f6933ac0ddcd6 100644
--- a/Programs/test_frozenmain.h
+++ b/Programs/test_frozenmain.h
@@ -1,37 +1,37 @@
// Auto-generated by Programs/freeze_test_frozenmain.py
unsigned char M_test_frozenmain[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,
- 0,0,0,0,0,243,170,0,0,0,149,0,90,0,80,0,
- 71,0,112,0,90,0,80,0,71,1,112,1,89,2,32,0,
- 80,1,50,1,0,0,0,0,0,0,30,0,89,2,32,0,
- 80,2,89,0,78,6,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,50,2,0,0,0,0,0,0,
- 30,0,89,1,78,8,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,32,0,50,0,0,0,0,0,
- 0,0,80,3,2,0,0,0,112,5,80,4,16,0,68,21,
- 0,0,28,0,112,6,89,2,32,0,80,5,89,6,12,0,
- 80,6,89,5,89,6,2,0,0,0,12,0,48,4,50,1,
- 0,0,0,0,0,0,30,0,73,23,0,0,9,0,30,0,
- 80,0,34,0,41,7,78,122,18,70,114,111,122,101,110,32,
- 72,101,108,108,111,32,87,111,114,108,100,122,8,115,121,115,
- 46,97,114,103,118,218,6,99,111,110,102,105,103,41,5,218,
- 12,112,114,111,103,114,97,109,95,110,97,109,101,218,10,101,
- 120,101,99,117,116,97,98,108,101,218,15,117,115,101,95,101,
- 110,118,105,114,111,110,109,101,110,116,218,17,99,111,110,102,
- 105,103,117,114,101,95,99,95,115,116,100,105,111,218,14,98,
- 117,102,102,101,114,101,100,95,115,116,100,105,111,122,7,99,
- 111,110,102,105,103,32,122,2,58,32,41,7,218,3,115,121,
- 115,218,17,95,116,101,115,116,105,110,116,101,114,110,97,108,
- 99,97,112,105,218,5,112,114,105,110,116,218,4,97,114,103,
- 118,218,11,103,101,116,95,99,111,110,102,105,103,115,114,2,
- 0,0,0,218,3,107,101,121,169,0,243,0,0,0,0,218,
- 18,116,101,115,116,95,102,114,111,122,101,110,109,97,105,110,
- 46,112,121,218,8,60,109,111,100,117,108,101,62,114,17,0,
- 0,0,1,0,0,0,115,94,0,0,0,240,3,1,1,1,
- 243,8,0,1,11,219,0,24,225,0,5,208,6,26,212,0,
- 27,217,0,5,128,106,144,35,151,40,145,40,212,0,27,216,
- 9,26,215,9,38,210,9,38,211,9,40,168,24,209,9,50,
- 128,6,244,2,6,12,2,128,67,241,14,0,5,10,136,71,
- 144,67,144,53,152,2,152,54,160,35,153,59,152,45,208,10,
- 40,214,4,41,243,15,6,12,2,114,15,0,0,0,
+ 0,0,0,0,0,243,168,0,0,0,149,0,91,0,81,0,
+ 72,0,113,0,91,0,81,0,72,1,113,1,90,2,33,0,
+ 81,1,51,1,0,0,0,0,0,0,31,0,90,2,33,0,
+ 81,2,90,0,79,6,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,51,2,0,0,0,0,0,0,
+ 31,0,90,1,79,8,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,33,0,51,0,0,0,0,0,
+ 0,0,81,3,2,0,0,0,113,5,81,4,16,0,69,20,
+ 0,0,113,6,90,2,33,0,81,5,90,6,12,0,81,6,
+ 90,5,90,6,2,0,0,0,12,0,49,4,51,1,0,0,
+ 0,0,0,0,31,0,74,22,0,0,9,0,30,0,81,0,
+ 35,0,41,7,78,122,18,70,114,111,122,101,110,32,72,101,
+ 108,108,111,32,87,111,114,108,100,122,8,115,121,115,46,97,
+ 114,103,118,218,6,99,111,110,102,105,103,41,5,218,12,112,
+ 114,111,103,114,97,109,95,110,97,109,101,218,10,101,120,101,
+ 99,117,116,97,98,108,101,218,15,117,115,101,95,101,110,118,
+ 105,114,111,110,109,101,110,116,218,17,99,111,110,102,105,103,
+ 117,114,101,95,99,95,115,116,100,105,111,218,14,98,117,102,
+ 102,101,114,101,100,95,115,116,100,105,111,122,7,99,111,110,
+ 102,105,103,32,122,2,58,32,41,7,218,3,115,121,115,218,
+ 17,95,116,101,115,116,105,110,116,101,114,110,97,108,99,97,
+ 112,105,218,5,112,114,105,110,116,218,4,97,114,103,118,218,
+ 11,103,101,116,95,99,111,110,102,105,103,115,114,2,0,0,
+ 0,218,3,107,101,121,169,0,243,0,0,0,0,218,18,116,
+ 101,115,116,95,102,114,111,122,101,110,109,97,105,110,46,112,
+ 121,218,8,60,109,111,100,117,108,101,62,114,17,0,0,0,
+ 1,0,0,0,115,94,0,0,0,240,3,1,1,1,243,8,
+ 0,1,11,219,0,24,225,0,5,208,6,26,212,0,27,217,
+ 0,5,128,106,144,35,151,40,145,40,212,0,27,216,9,26,
+ 215,9,38,210,9,38,211,9,40,168,24,209,9,50,128,6,
+ 243,2,6,12,2,128,67,241,14,0,5,10,136,71,144,67,
+ 144,53,152,2,152,54,160,35,153,59,152,45,208,10,40,214,
+ 4,41,243,15,6,12,2,114,15,0,0,0,
};
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 602cf7f47b812b..4961693c7e654a 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -60,6 +60,8 @@
#define specializing
#define split
#define replicate(TIMES)
+#define tier1
+#define no_save_ip
// Dummy variables for stack effects.
static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub;
@@ -336,9 +338,18 @@ dummy_func(
res = PyStackRef_NULL;
}
- macro(END_FOR) = POP_TOP;
+ no_save_ip inst(END_FOR, (value -- )) {
+ /* Don't update instr_ptr, so that POP_ITER sees
+ * the FOR_ITER as the previous instruction.
+ * This has the benign side effect that if value is
+ * finalized it will see the location as the FOR_ITER's.
+ */
+ PyStackRef_CLOSE(value);
+ }
+
+ macro(POP_ITER) = POP_TOP;
- tier1 inst(INSTRUMENTED_END_FOR, (receiver, value -- receiver)) {
+ no_save_ip tier1 inst(INSTRUMENTED_END_FOR, (receiver, value -- receiver)) {
/* Need to create a fake StopIteration error here,
* to conform to PEP 380 */
if (PyStackRef_GenCheck(receiver)) {
@@ -350,6 +361,11 @@ dummy_func(
DECREF_INPUTS();
}
+ tier1 inst(INSTRUMENTED_POP_ITER, (iter -- )) {
+ INSTRUMENTED_JUMP(prev_instr, this_instr+1, PY_MONITORING_EVENT_BRANCH_RIGHT);
+ PyStackRef_CLOSE(iter);
+ }
+
pure inst(END_SEND, (receiver, value -- val)) {
(void)receiver;
val = value;
@@ -2924,10 +2940,8 @@ dummy_func(
/* iterator ended normally */
assert(next_instr[oparg].op.code == END_FOR ||
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
- PyStackRef_CLOSE(iter);
- STACK_SHRINK(1);
- /* Jump forward oparg, then skip following END_FOR and POP_TOP instruction */
- JUMPBY(oparg + 2);
+ /* Jump forward oparg, then skip following END_FOR */
+ JUMPBY(oparg + 1);
DISPATCH();
}
next = PyStackRef_FromPyObjectSteal(next_o);
@@ -2957,12 +2971,14 @@ dummy_func(
macro(FOR_ITER) = _SPECIALIZE_FOR_ITER + _FOR_ITER;
+
inst(INSTRUMENTED_FOR_ITER, (unused/1 -- )) {
_PyStackRef iter_stackref = TOP();
PyObject *iter = PyStackRef_AsPyObjectBorrow(iter_stackref);
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
if (next != NULL) {
PUSH(PyStackRef_FromPyObjectSteal(next));
+ INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
}
else {
if (_PyErr_Occurred(tstate)) {
@@ -2976,14 +2992,12 @@ dummy_func(
/* iterator ended normally */
assert(next_instr[oparg].op.code == END_FOR ||
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
- STACK_SHRINK(1);
- PyStackRef_CLOSE(iter_stackref);
- /* Skip END_FOR and POP_TOP */
- _Py_CODEUNIT *target = next_instr + oparg + 2;
- INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH_RIGHT);
+ /* Skip END_FOR */
+ JUMPBY(oparg + 1);
}
}
+
op(_ITER_CHECK_LIST, (iter -- iter)) {
EXIT_IF(Py_TYPE(PyStackRef_AsPyObjectBorrow(iter)) != &PyListIter_Type);
}
@@ -3002,10 +3016,8 @@ dummy_func(
Py_DECREF(seq);
}
#endif
- PyStackRef_CLOSE(iter);
- STACK_SHRINK(1);
- /* Jump forward oparg, then skip following END_FOR and POP_TOP instructions */
- JUMPBY(oparg + 2);
+ /* Jump forward oparg, then skip following END_FOR instruction */
+ JUMPBY(oparg + 1);
DISPATCH();
}
}
@@ -3054,10 +3066,8 @@ dummy_func(
it->it_seq = NULL;
Py_DECREF(seq);
}
- PyStackRef_CLOSE(iter);
- STACK_SHRINK(1);
- /* Jump forward oparg, then skip following END_FOR and POP_TOP instructions */
- JUMPBY(oparg + 2);
+ /* Jump forward oparg, then skip following END_FOR instruction */
+ JUMPBY(oparg + 1);
DISPATCH();
}
}
@@ -3098,10 +3108,8 @@ dummy_func(
assert(Py_TYPE(r) == &PyRangeIter_Type);
STAT_INC(FOR_ITER, hit);
if (r->len <= 0) {
- STACK_SHRINK(1);
- PyStackRef_CLOSE(iter);
- // Jump over END_FOR and POP_TOP instructions.
- JUMPBY(oparg + 2);
+ // Jump over END_FOR instruction.
+ JUMPBY(oparg + 1);
DISPATCH();
}
}
@@ -4779,7 +4787,8 @@ dummy_func(
}
inst(INSTRUMENTED_NOT_TAKEN, ( -- )) {
- INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
+ (void)this_instr; // INSTRUMENTED_JUMP requires this_instr
+ INSTRUMENTED_JUMP(prev_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
}
macro(INSTRUMENTED_JUMP_BACKWARD) =
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index f15633fa467376..c37e1cf3afa60e 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -363,7 +363,7 @@ do { \
next_instr = dest; \
} else { \
_PyFrame_SetStackPointer(frame, stack_pointer); \
- next_instr = _Py_call_instrumentation_jump(tstate, event, frame, src, dest); \
+ next_instr = _Py_call_instrumentation_jump(this_instr, tstate, event, frame, src, dest); \
stack_pointer = _PyFrame_GetStackPointer(frame); \
if (next_instr == NULL) { \
next_instr = (dest)+1; \
diff --git a/Python/codegen.c b/Python/codegen.c
index 7432415b17414e..14f9f5ad1254f5 100644
--- a/Python/codegen.c
+++ b/Python/codegen.c
@@ -409,7 +409,7 @@ codegen_addop_j(instr_sequence *seq, location loc,
if (_PyInstructionSequence_Addop(seq, opcode, target.id, loc) != SUCCESS) {
return ERROR;
}
- if (IS_CONDITIONAL_JUMP_OPCODE(opcode) || opcode == FOR_ITER) {
+ if (IS_CONDITIONAL_JUMP_OPCODE(opcode)) {
return _PyInstructionSequence_Addop(seq, NOT_TAKEN, 0, NO_LOCATION);
}
return SUCCESS;
@@ -2018,7 +2018,7 @@ codegen_for(compiler *c, stmt_ty s)
* but a non-generator will jump to a later instruction.
*/
ADDOP(c, NO_LOCATION, END_FOR);
- ADDOP(c, NO_LOCATION, POP_TOP);
+ ADDOP(c, NO_LOCATION, POP_ITER);
_PyCompile_PopFBlock(c, COMPILE_FBLOCK_FOR_LOOP, start);
@@ -4283,7 +4283,7 @@ codegen_sync_comprehension_generator(compiler *c, location loc,
* but a non-generator will jump to a later instruction.
*/
ADDOP(c, NO_LOCATION, END_FOR);
- ADDOP(c, NO_LOCATION, POP_TOP);
+ ADDOP(c, NO_LOCATION, POP_ITER);
}
return SUCCESS;
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index f7374d52705960..ac2f69b7e98dc3 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -411,6 +411,20 @@
break;
}
+ case _END_FOR: {
+ _PyStackRef value;
+ value = stack_pointer[-1];
+ /* Don't update instr_ptr, so that POP_ITER sees
+ * the FOR_ITER as the previous instruction.
+ * This has the benign side effect that if value is
+ * finalized it will see the location as the FOR_ITER's.
+ */
+ PyStackRef_CLOSE(value);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
case _END_SEND: {
_PyStackRef value;
_PyStackRef receiver;
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 98743c27c38524..b73844ca2d9542 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -3768,11 +3768,15 @@
}
TARGET(END_FOR) {
- frame->instr_ptr = next_instr;
next_instr += 1;
INSTRUCTION_STATS(END_FOR);
_PyStackRef value;
value = stack_pointer[-1];
+ /* Don't update instr_ptr, so that POP_ITER sees
+ * the FOR_ITER as the previous instruction.
+ * This has the benign side effect that if value is
+ * finalized it will see the location as the FOR_ITER's.
+ */
PyStackRef_CLOSE(value);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
@@ -3957,10 +3961,8 @@
/* iterator ended normally */
assert(next_instr[oparg].op.code == END_FOR ||
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
- PyStackRef_CLOSE(iter);
- STACK_SHRINK(1);
- /* Jump forward oparg, then skip following END_FOR and POP_TOP instruction */
- JUMPBY(oparg + 2);
+ /* Jump forward oparg, then skip following END_FOR */
+ JUMPBY(oparg + 1);
DISPATCH();
}
next = PyStackRef_FromPyObjectSteal(next_o);
@@ -4048,10 +4050,8 @@
Py_DECREF(seq);
}
#endif
- PyStackRef_CLOSE(iter);
- STACK_SHRINK(1);
- /* Jump forward oparg, then skip following END_FOR and POP_TOP instructions */
- JUMPBY(oparg + 2);
+ /* Jump forward oparg, then skip following END_FOR instruction */
+ JUMPBY(oparg + 1);
DISPATCH();
}
}
@@ -4091,10 +4091,8 @@
assert(Py_TYPE(r) == &PyRangeIter_Type);
STAT_INC(FOR_ITER, hit);
if (r->len <= 0) {
- STACK_SHRINK(1);
- PyStackRef_CLOSE(iter);
- // Jump over END_FOR and POP_TOP instructions.
- JUMPBY(oparg + 2);
+ // Jump over END_FOR instruction.
+ JUMPBY(oparg + 1);
DISPATCH();
}
}
@@ -4141,10 +4139,8 @@
it->it_seq = NULL;
Py_DECREF(seq);
}
- PyStackRef_CLOSE(iter);
- STACK_SHRINK(1);
- /* Jump forward oparg, then skip following END_FOR and POP_TOP instructions */
- JUMPBY(oparg + 2);
+ /* Jump forward oparg, then skip following END_FOR instruction */
+ JUMPBY(oparg + 1);
DISPATCH();
}
}
@@ -4572,7 +4568,7 @@
}
TARGET(INSTRUMENTED_END_FOR) {
- _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
+ _Py_CODEUNIT* const this_instr = next_instr;
(void)this_instr;
next_instr += 1;
INSTRUCTION_STATS(INSTRUMENTED_END_FOR);
@@ -4636,6 +4632,7 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
if (next != NULL) {
PUSH(PyStackRef_FromPyObjectSteal(next));
+ INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
}
else {
if (_PyErr_Occurred(tstate)) {
@@ -4653,11 +4650,8 @@
/* iterator ended normally */
assert(next_instr[oparg].op.code == END_FOR ||
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
- STACK_SHRINK(1);
- PyStackRef_CLOSE(iter_stackref);
- /* Skip END_FOR and POP_TOP */
- _Py_CODEUNIT *target = next_instr + oparg + 2;
- INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH_RIGHT);
+ /* Skip END_FOR */
+ JUMPBY(oparg + 1);
}
DISPATCH();
}
@@ -4764,11 +4758,28 @@
}
TARGET(INSTRUMENTED_NOT_TAKEN) {
+ _Py_CODEUNIT* const prev_instr = frame->instr_ptr;
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
(void)this_instr;
next_instr += 1;
INSTRUCTION_STATS(INSTRUMENTED_NOT_TAKEN);
- INSTRUMENTED_JUMP(this_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
+ (void)this_instr; // INSTRUMENTED_JUMP requires this_instr
+ INSTRUMENTED_JUMP(prev_instr, next_instr, PY_MONITORING_EVENT_BRANCH_LEFT);
+ DISPATCH();
+ }
+
+ TARGET(INSTRUMENTED_POP_ITER) {
+ _Py_CODEUNIT* const prev_instr = frame->instr_ptr;
+ _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
+ (void)this_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_POP_ITER);
+ _PyStackRef iter;
+ iter = stack_pointer[-1];
+ INSTRUMENTED_JUMP(prev_instr, this_instr+1, PY_MONITORING_EVENT_BRANCH_RIGHT);
+ PyStackRef_CLOSE(iter);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
DISPATCH();
}
@@ -6693,6 +6704,18 @@
DISPATCH();
}
+ TARGET(POP_ITER) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(POP_ITER);
+ _PyStackRef value;
+ value = stack_pointer[-1];
+ PyStackRef_CLOSE(value);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ DISPATCH();
+ }
+
TARGET(POP_JUMP_IF_FALSE) {
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
(void)this_instr;
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index e4255bfad8c41a..17e5346be5ed3d 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -14,6 +14,7 @@
#include "pycore_namespace.h"
#include "pycore_object.h"
#include "pycore_opcode_metadata.h" // IS_VALID_OPCODE, _PyOpcode_Caches
+#include "pycore_opcode_utils.h" // IS_CONDITIONAL_JUMP_OPCODE
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_UINTPTR_RELEASE
#include "pycore_pyerrors.h"
#include "pycore_pystate.h" // _PyInterpreterState_GET()
@@ -95,8 +96,10 @@ static const int8_t EVENT_FOR_OPCODE[256] = {
[INSTRUMENTED_POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
[INSTRUMENTED_POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH_RIGHT,
- [FOR_ITER] = PY_MONITORING_EVENT_BRANCH_RIGHT,
- [INSTRUMENTED_FOR_ITER] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [FOR_ITER] = PY_MONITORING_EVENT_BRANCH_LEFT,
+ [INSTRUMENTED_FOR_ITER] = PY_MONITORING_EVENT_BRANCH_LEFT,
+ [POP_ITER] = PY_MONITORING_EVENT_BRANCH_RIGHT,
+ [INSTRUMENTED_POP_ITER] = PY_MONITORING_EVENT_BRANCH_RIGHT,
[END_FOR] = PY_MONITORING_EVENT_STOP_ITERATION,
[INSTRUMENTED_END_FOR] = PY_MONITORING_EVENT_STOP_ITERATION,
[END_SEND] = PY_MONITORING_EVENT_STOP_ITERATION,
@@ -119,6 +122,7 @@ static const uint8_t DE_INSTRUMENT[256] = {
[INSTRUMENTED_POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
[INSTRUMENTED_FOR_ITER] = FOR_ITER,
+ [INSTRUMENTED_POP_ITER] = POP_ITER,
[INSTRUMENTED_END_FOR] = END_FOR,
[INSTRUMENTED_END_SEND] = END_SEND,
[INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
@@ -156,6 +160,8 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = {
[INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
[FOR_ITER] = INSTRUMENTED_FOR_ITER,
[INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
+ [POP_ITER] = INSTRUMENTED_POP_ITER,
+ [INSTRUMENTED_POP_ITER] = INSTRUMENTED_POP_ITER,
[LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
[INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
[NOT_TAKEN] = INSTRUMENTED_NOT_TAKEN,
@@ -1077,8 +1083,8 @@ static const char *const event_names [] = {
static int
call_instrumentation_vector(
- PyThreadState *tstate, int event,
- _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, Py_ssize_t nargs, PyObject *args[])
+ _Py_CODEUNIT *instr, PyThreadState *tstate, int event,
+ _PyInterpreterFrame *frame, _Py_CODEUNIT *arg2, Py_ssize_t nargs, PyObject *args[])
{
if (tstate->tracing) {
return 0;
@@ -1091,17 +1097,13 @@ call_instrumentation_vector(
int offset = (int)(instr - _PyFrame_GetBytecode(frame));
/* Offset visible to user should be the offset in bytes, as that is the
* convention for APIs involving code offsets. */
- int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT);
- if (event == PY_MONITORING_EVENT_BRANCH_LEFT) {
- assert(EVENT_FOR_OPCODE[_Py_GetBaseCodeUnit(code, offset-2).op.code] == PY_MONITORING_EVENT_BRANCH_RIGHT);
- bytes_offset -= 4;
- }
- PyObject *offset_obj = PyLong_FromLong(bytes_offset);
- if (offset_obj == NULL) {
+ int bytes_arg2 = (int)(arg2 - _PyFrame_GetBytecode(frame)) * (int)sizeof(_Py_CODEUNIT);
+ PyObject *arg2_obj = PyLong_FromLong(bytes_arg2);
+ if (arg2_obj == NULL) {
return -1;
}
assert(args[2] == NULL);
- args[2] = offset_obj;
+ args[2] = arg2_obj;
PyInterpreterState *interp = tstate->interp;
uint8_t tools = get_tools_for_instruction(code, interp, offset, event);
size_t nargsf = (size_t) nargs | PY_VECTORCALL_ARGUMENTS_OFFSET;
@@ -1139,7 +1141,7 @@ call_instrumentation_vector(
}
}
}
- Py_DECREF(offset_obj);
+ Py_DECREF(arg2_obj);
return err;
}
@@ -1149,7 +1151,7 @@ _Py_call_instrumentation(
_PyInterpreterFrame *frame, _Py_CODEUNIT *instr)
{
PyObject *args[3] = { NULL, NULL, NULL };
- return call_instrumentation_vector(tstate, event, frame, instr, 2, args);
+ return call_instrumentation_vector(instr, tstate, event, frame, instr, 2, args);
}
int
@@ -1158,7 +1160,7 @@ _Py_call_instrumentation_arg(
_PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg)
{
PyObject *args[4] = { NULL, NULL, NULL, arg };
- return call_instrumentation_vector(tstate, event, frame, instr, 3, args);
+ return call_instrumentation_vector(instr, tstate, event, frame, instr, 3, args);
}
int
@@ -1167,34 +1169,34 @@ _Py_call_instrumentation_2args(
_PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1)
{
PyObject *args[5] = { NULL, NULL, NULL, arg0, arg1 };
- return call_instrumentation_vector(tstate, event, frame, instr, 4, args);
+ return call_instrumentation_vector(instr, tstate, event, frame, instr, 4, args);
}
_Py_CODEUNIT *
_Py_call_instrumentation_jump(
- PyThreadState *tstate, int event,
- _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *target)
+ _Py_CODEUNIT *instr, PyThreadState *tstate, int event,
+ _PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest)
{
assert(event == PY_MONITORING_EVENT_JUMP ||
event == PY_MONITORING_EVENT_BRANCH_RIGHT ||
event == PY_MONITORING_EVENT_BRANCH_LEFT);
- assert(frame->instr_ptr == instr);
- int to = (int)(target - _PyFrame_GetBytecode(frame));
+ int to = (int)(dest - _PyFrame_GetBytecode(frame));
PyObject *to_obj = PyLong_FromLong(to * (int)sizeof(_Py_CODEUNIT));
if (to_obj == NULL) {
return NULL;
}
PyObject *args[4] = { NULL, NULL, NULL, to_obj };
- int err = call_instrumentation_vector(tstate, event, frame, instr, 3, args);
+ _Py_CODEUNIT *instr_ptr = frame->instr_ptr;
+ int err = call_instrumentation_vector(instr, tstate, event, frame, src, 3, args);
Py_DECREF(to_obj);
if (err) {
return NULL;
}
- if (frame->instr_ptr != instr) {
+ if (frame->instr_ptr != instr_ptr) {
/* The callback has caused a jump (by setting the line number) */
return frame->instr_ptr;
}
- return target;
+ return dest;
}
static void
@@ -1204,7 +1206,7 @@ call_instrumentation_vector_protected(
{
assert(_PyErr_Occurred(tstate));
PyObject *exc = _PyErr_GetRaisedException(tstate);
- int err = call_instrumentation_vector(tstate, event, frame, instr, nargs, args);
+ int err = call_instrumentation_vector(instr, tstate, event, frame, instr, nargs, args);
if (err) {
Py_XDECREF(exc);
}
@@ -1496,9 +1498,10 @@ initialize_lines(PyCodeObject *code)
case END_FOR:
case END_SEND:
case RESUME:
+ case POP_ITER:
/* END_FOR cannot start a line, as it is skipped by FOR_ITER
* END_SEND cannot start a line, as it is skipped by SEND
- * RESUME must not be instrumented with INSTRUMENT_LINE */
+ * RESUME and POP_ITER must not be instrumented with INSTRUMENT_LINE */
line_data[i].original_opcode = 0;
break;
default:
@@ -1570,11 +1573,14 @@ initialize_lines(PyCodeObject *code)
}
assert(target >= 0);
if (line_data[target].line_delta != NO_LINE) {
- line_data[target].original_opcode = _Py_GetBaseCodeUnit(code, target).op.code;
- if (line_data[target].line_delta == COMPUTED_LINE_LINENO_CHANGE) {
- // If the line is a jump target, we are not sure if the line
- // number changes, so we set it to COMPUTED_LINE.
- line_data[target].line_delta = COMPUTED_LINE;
+ int opcode = _Py_GetBaseCodeUnit(code, target).op.code;
+ if (opcode != POP_ITER) {
+ line_data[target].original_opcode = opcode;
+ if (line_data[target].line_delta == COMPUTED_LINE_LINENO_CHANGE) {
+ // If the line is a jump target, we are not sure if the line
+ // number changes, so we set it to COMPUTED_LINE.
+ line_data[target].line_delta = COMPUTED_LINE;
+ }
}
}
}
@@ -2887,30 +2893,52 @@ branch_handler(
_PyLegacyBranchEventHandler *self, PyObject *const *args,
size_t nargsf, PyObject *kwnames
) {
+ // Find the other instrumented instruction and remove tool
+ // The spec (PEP 669) allows spurious events after a DISABLE,
+ // so a best effort is good enough.
+ assert(PyVectorcall_NARGS(nargsf) >= 3);
+ PyCodeObject *code = (PyCodeObject *)args[0];
+ int src_offset = PyLong_AsLong(args[1]);
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ _Py_CODEUNIT instr = _PyCode_CODE(code)[src_offset/2];
+ if (!is_instrumented(instr.op.code)) {
+ /* Already disabled */
+ return &_PyInstrumentation_DISABLE;
+ }
PyObject *res = PyObject_Vectorcall(self->handler, args, nargsf, kwnames);
if (res == &_PyInstrumentation_DISABLE) {
- // Find the other instrumented instruction and remove tool
- assert(PyVectorcall_NARGS(nargsf) >= 2);
- PyObject *offset_obj = args[1];
- int bytes_offset = PyLong_AsLong(offset_obj);
- if (PyErr_Occurred()) {
- return NULL;
- }
- PyCodeObject *code = (PyCodeObject *)args[0];
- if (!PyCode_Check(code) || (bytes_offset & 1)) {
- return res;
- }
- int offset = bytes_offset / 2;
/* We need FOR_ITER and POP_JUMP_ to be the same size */
assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1);
- if (self->right) {
- offset += 2;
+ int offset;
+ int other_event;
+ if (instr.op.code == FOR_ITER) {
+ if (self->right) {
+ offset = src_offset/2;
+ other_event = PY_MONITORING_EVENT_BRANCH_LEFT;
+ }
+ else {
+ // We don't know where the POP_ITER is, so
+ // we cannot de-instrument it.
+ return res;
+ }
+ }
+ else if (IS_CONDITIONAL_JUMP_OPCODE(instr.op.code)) {
+ if (self->right) {
+ offset = src_offset/2 + 2;
+ other_event = PY_MONITORING_EVENT_BRANCH_LEFT;
+ assert(_Py_GetBaseCodeUnit(code, offset).op.code == NOT_TAKEN);
+ }
+ else {
+ offset = src_offset/2;
+ other_event = PY_MONITORING_EVENT_BRANCH_RIGHT;
+ }
}
- if (offset >= Py_SIZE(code)) {
+ else {
+ // Orphaned NOT_TAKEN -- Jump removed by the compiler
return res;
}
- int other_event = self->right ?
- PY_MONITORING_EVENT_BRANCH_LEFT : PY_MONITORING_EVENT_BRANCH_RIGHT;
LOCK_CODE(code);
remove_tools(code, offset, other_event, 1 << self->tool_id);
UNLOCK_CODE();
@@ -3013,15 +3041,30 @@ static PyObject *
branchesiter_next(branchesiterator *bi)
{
int offset = bi->bi_offset;
+ int oparg = 0;
while (offset < Py_SIZE(bi->bi_code)) {
_Py_CODEUNIT inst = _Py_GetBaseCodeUnit(bi->bi_code, offset);
- int next_offset = offset + _PyInstruction_GetLength(bi->bi_code, offset);
- int event = EVENT_FOR_OPCODE[inst.op.code];
- if (event == PY_MONITORING_EVENT_BRANCH_RIGHT) {
- /* Skip NOT_TAKEN */
- int not_taken = next_offset + 1;
- bi->bi_offset = not_taken;
- return int_triple(offset*2, not_taken*2, (next_offset + inst.op.arg)*2);
+ int next_offset = offset + 1 + _PyOpcode_Caches[inst.op.code];
+ switch(inst.op.code) {
+ case EXTENDED_ARG:
+ oparg = (oparg << 8) | inst.op.arg;
+ break;
+ case FOR_ITER:
+ oparg = (oparg << 8) | inst.op.arg;
+ bi->bi_offset = next_offset;
+ int target = next_offset + oparg+2; // Skips END_FOR and POP_ITER
+ return int_triple(offset*2, next_offset*2, target*2);
+ case POP_JUMP_IF_FALSE:
+ case POP_JUMP_IF_TRUE:
+ case POP_JUMP_IF_NONE:
+ case POP_JUMP_IF_NOT_NONE:
+ oparg = (oparg << 8) | inst.op.arg;
+ /* Skip NOT_TAKEN */
+ int not_taken = next_offset + 1;
+ bi->bi_offset = not_taken;
+ return int_triple(offset*2, not_taken*2, (next_offset + oparg)*2);
+ default:
+ oparg = 0;
}
offset = next_offset;
}
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 7f3fb9c9a63dd1..00d55d3a82edc1 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -29,6 +29,7 @@ static void *opcode_targets[256] = {
&&TARGET_NOP,
&&TARGET_NOT_TAKEN,
&&TARGET_POP_EXCEPT,
+ &&TARGET_POP_ITER,
&&TARGET_POP_TOP,
&&TARGET_PUSH_EXC_INFO,
&&TARGET_PUSH_NULL,
@@ -147,7 +148,6 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_RESUME,
&&TARGET_BINARY_OP_ADD_FLOAT,
&&TARGET_BINARY_OP_ADD_INT,
@@ -234,8 +234,8 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_INSTRUMENTED_END_FOR,
+ &&TARGET_INSTRUMENTED_POP_ITER,
&&TARGET_INSTRUMENTED_END_SEND,
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
&&TARGET_INSTRUMENTED_FOR_ITER,
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 6a4d20fad76c15..52b3f0a84afedf 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -622,8 +622,14 @@ translate_bytecode_to_trace(
goto done;
}
assert(opcode != ENTER_EXECUTOR && opcode != EXTENDED_ARG);
- RESERVE_RAW(2, "_CHECK_VALIDITY_AND_SET_IP");
- ADD_TO_TRACE(_CHECK_VALIDITY_AND_SET_IP, 0, (uintptr_t)instr, target);
+ if (OPCODE_HAS_NO_SAVE_IP(opcode)) {
+ RESERVE_RAW(2, "_CHECK_VALIDITY");
+ ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target);
+ }
+ else {
+ RESERVE_RAW(2, "_CHECK_VALIDITY_AND_SET_IP");
+ ADD_TO_TRACE(_CHECK_VALIDITY_AND_SET_IP, 0, (uintptr_t)instr, target);
+ }
/* Special case the first instruction,
* so that we can guarantee forward progress */
@@ -771,7 +777,7 @@ translate_bytecode_to_trace(
uint32_t next_inst = target + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + (oparg > 255);
uint32_t jump_target = next_inst + oparg;
assert(_Py_GetBaseCodeUnit(code, jump_target).op.code == END_FOR);
- assert(_Py_GetBaseCodeUnit(code, jump_target+1).op.code == POP_TOP);
+ assert(_Py_GetBaseCodeUnit(code, jump_target+1).op.code == POP_ITER);
}
#endif
break;
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 0fcf5e18ed5808..be3e06108aec92 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -115,6 +115,12 @@
break;
}
+ case _END_FOR: {
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
case _END_SEND: {
_Py_UopsSymbol *val;
val = sym_new_not_null(ctx);
diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py
index 73c871759afbf5..c0a370a936aa94 100644
--- a/Tools/cases_generator/analyzer.py
+++ b/Tools/cases_generator/analyzer.py
@@ -27,6 +27,7 @@ class Properties:
oparg_and_1: bool = False
const_oparg: int = -1
needs_prev: bool = False
+ no_save_ip: bool = False
def dump(self, indent: str) -> None:
simple_properties = self.__dict__.copy()
@@ -60,6 +61,7 @@ def from_list(properties: list["Properties"]) -> "Properties":
side_exit=any(p.side_exit for p in properties),
pure=all(p.pure for p in properties),
needs_prev=any(p.needs_prev for p in properties),
+ no_save_ip=all(p.no_save_ip for p in properties),
)
@property
@@ -87,6 +89,7 @@ def escapes(self) -> bool:
has_free=False,
side_exit=False,
pure=True,
+ no_save_ip=False,
)
@@ -829,6 +832,7 @@ def compute_properties(op: parser.InstDef) -> Properties:
and not has_free,
has_free=has_free,
pure="pure" in op.annotations,
+ no_save_ip="no_save_ip" in op.annotations,
tier=tier_variable(op),
needs_prev=variable_used(op, "prev_instr"),
)
diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py
index d17617cab0266b..8df9a9cada92ae 100644
--- a/Tools/cases_generator/generators_common.py
+++ b/Tools/cases_generator/generators_common.py
@@ -583,6 +583,8 @@ def cflags(p: Properties) -> str:
flags.append("HAS_ESCAPES_FLAG")
if p.pure:
flags.append("HAS_PURE_FLAG")
+ if p.no_save_ip:
+ flags.append("HAS_NO_SAVE_IP_FLAG")
if p.oparg_and_1:
flags.append("HAS_OPARG_AND_1_FLAG")
if flags:
diff --git a/Tools/cases_generator/lexer.py b/Tools/cases_generator/lexer.py
index 37f96398ff175f..bee2a185745f4d 100644
--- a/Tools/cases_generator/lexer.py
+++ b/Tools/cases_generator/lexer.py
@@ -226,6 +226,7 @@ def choice(*opts: str) -> str:
"replicate",
"tier1",
"tier2",
+ "no_save_ip",
}
__all__ = []
diff --git a/Tools/cases_generator/opcode_metadata_generator.py b/Tools/cases_generator/opcode_metadata_generator.py
index 1a9849c0cbbb25..453db6905d6842 100644
--- a/Tools/cases_generator/opcode_metadata_generator.py
+++ b/Tools/cases_generator/opcode_metadata_generator.py
@@ -53,6 +53,7 @@
"PASSTHROUGH",
"OPARG_AND_1",
"ERROR_NO_POP",
+ "NO_SAVE_IP",
]
@@ -285,8 +286,8 @@ def generate_metadata_table(analysis: Analysis, out: CWriter) -> None:
table_size = 256 + len(analysis.pseudos)
out.emit("struct opcode_metadata {\n")
out.emit("uint8_t valid_entry;\n")
- out.emit("int8_t instr_format;\n")
- out.emit("int16_t flags;\n")
+ out.emit("uint8_t instr_format;\n")
+ out.emit("uint16_t flags;\n")
out.emit("};\n\n")
out.emit(
f"extern const struct opcode_metadata _PyOpcode_opcode_metadata[{table_size}];\n"
diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py
index fcdd3bdacd0e7a..40562da99b20ea 100644
--- a/Tools/cases_generator/tier1_generator.py
+++ b/Tools/cases_generator/tier1_generator.py
@@ -151,9 +151,12 @@ def generate_tier1(
if inst.properties.needs_prev:
out.emit(f"_Py_CODEUNIT* const prev_instr = frame->instr_ptr;\n")
if needs_this and not inst.is_target:
- out.emit(f"_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;\n")
+ if inst.properties.no_save_ip:
+ out.emit(f"_Py_CODEUNIT* const this_instr = next_instr;\n")
+ else:
+ out.emit(f"_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;\n")
out.emit(unused_guard)
- else:
+ elif not inst.properties.no_save_ip:
out.emit(f"frame->instr_ptr = next_instr;\n")
out.emit(f"next_instr += {inst.size};\n")
out.emit(f"INSTRUCTION_STATS({name});\n")
1
0
06 Jan '25
https://github.com/python/cpython/commit/b9c693dcca01537eee1ef716ffebc632be…
commit: b9c693dcca01537eee1ef716ffebc632be37594b
branch: main
author: Mark Shannon <mark(a)hotpy.org>
committer: markshannon <mark(a)hotpy.org>
date: 2025-01-06T14:16:22Z
summary:
GH-128073: Include `EXIT_IF` when checking for escaping calls (GH-128537)
files:
M Lib/test/test_generated_cases.py
M Tools/cases_generator/analyzer.py
diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py
index 9c65e81dfe4be1..75cbd8dd94e9cb 100644
--- a/Lib/test/test_generated_cases.py
+++ b/Lib/test/test_generated_cases.py
@@ -1713,6 +1713,31 @@ def test_pop_dead_inputs_with_output(self):
"""
self.run_cases_test(input, output)
+ def test_no_escaping_calls_in_branching_macros(self):
+
+ input = """
+ inst(OP, ( -- )) {
+ DEOPT_IF(escaping_call());
+ }
+ """
+ with self.assertRaises(SyntaxError):
+ self.run_cases_test(input, "")
+
+ input = """
+ inst(OP, ( -- )) {
+ EXIT_IF(escaping_call());
+ }
+ """
+ with self.assertRaises(SyntaxError):
+ self.run_cases_test(input, "")
+
+ input = """
+ inst(OP, ( -- )) {
+ ERROR_IF(escaping_call(), error);
+ }
+ """
+ with self.assertRaises(SyntaxError):
+ self.run_cases_test(input, "")
class TestGeneratedAbstractCases(unittest.TestCase):
def setUp(self) -> None:
diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py
index eca851e6de87ae..73c871759afbf5 100644
--- a/Tools/cases_generator/analyzer.py
+++ b/Tools/cases_generator/analyzer.py
@@ -668,7 +668,7 @@ def check_escaping_calls(instr: parser.InstDef, escapes: dict[lexer.Token, tuple
if tkn.kind == "IF":
next(tkn_iter)
in_if = 1
- if tkn.kind == "IDENTIFIER" and tkn.text in ("DEOPT_IF", "ERROR_IF"):
+ if tkn.kind == "IDENTIFIER" and tkn.text in ("DEOPT_IF", "ERROR_IF", "EXIT_IF"):
next(tkn_iter)
in_if = 1
elif tkn.kind == "LPAREN" and in_if:
1
0
https://github.com/python/cpython/commit/f89e5e20cb8964653ea7d6f53d3e40953b…
commit: f89e5e20cb8964653ea7d6f53d3e40953b6548ce
branch: main
author: Victor Stinner <vstinner(a)python.org>
committer: vstinner <vstinner(a)python.org>
date: 2025-01-06T12:43:09Z
summary:
gh-127350: Add Py_fopen() and Py_fclose() functions (#127821)
files:
A Lib/test/test_capi/test_file.py
A Misc/NEWS.d/next/C_API/2024-12-11-13-01-26.gh-issue-127350.uEBZZ4.rst
A Modules/_testcapi/clinic/file.c.h
M Doc/c-api/sys.rst
M Doc/whatsnew/3.14.rst
M Include/cpython/fileutils.h
M Lib/test/test_ssl.py
M Modules/_ssl.c
M Modules/_ssl/debughelpers.c
M Modules/_testcapi/file.c
M Modules/_testcapi/object.c
M Modules/_testcapimodule.c
M Modules/main.c
M Python/errors.c
M Python/fileutils.c
M Python/import.c
M Python/pythonrun.c
M Python/sysmodule.c
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index c688afdca8231d..7a7d39aea20baf 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -216,6 +216,38 @@ Operating System Utilities
The function now uses the UTF-8 encoding on Windows if
:c:member:`PyPreConfig.legacy_windows_fs_encoding` is zero.
+.. c:function:: FILE* Py_fopen(PyObject *path, const char *mode)
+
+ Similar to :c:func:`!fopen`, but *path* is a Python object and
+ an exception is set on error.
+
+ *path* must be a :class:`str` object, a :class:`bytes` object,
+ or a :term:`path-like object`.
+
+ On success, return the new file pointer.
+ On error, set an exception and return ``NULL``.
+
+ The file must be closed by :c:func:`Py_fclose` rather than calling directly
+ :c:func:`!fclose`.
+
+ The file descriptor is created non-inheritable (:pep:`446`).
+
+ The caller must hold the GIL.
+
+ .. versionadded:: next
+
+
+.. c:function:: int Py_fclose(FILE *file)
+
+ Close a file that was opened by :c:func:`Py_fopen`.
+
+ On success, return ``0``.
+ On error, return ``EOF`` and ``errno`` is set to indicate the error.
+ In either case, any further access (including another call to
+ :c:func:`Py_fclose`) to the stream results in undefined behavior.
+
+ .. versionadded:: next
+
.. _systemfunctions:
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index f365db37217e95..16851b4e63ea2c 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -1237,6 +1237,12 @@ New features
:monitoring-event:`BRANCH_LEFT` and :monitoring-event:`BRANCH_RIGHT`
events, respectively.
+* Add :c:func:`Py_fopen` function to open a file. Similar to the
+ :c:func:`!fopen` function, but the *path* parameter is a Python object and an
+ exception is set on error. Add also :c:func:`Py_fclose` function to close a
+ file.
+ (Contributed by Victor Stinner in :gh:`127350`.)
+
Porting to Python 3.14
----------------------
diff --git a/Include/cpython/fileutils.h b/Include/cpython/fileutils.h
index b386ad107bde1f..702f89aca324c5 100644
--- a/Include/cpython/fileutils.h
+++ b/Include/cpython/fileutils.h
@@ -2,7 +2,13 @@
# error "this header file must not be included directly"
#endif
-// Used by _testcapi which must not use the internal C API
-PyAPI_FUNC(FILE*) _Py_fopen_obj(
+PyAPI_FUNC(FILE*) Py_fopen(
PyObject *path,
const char *mode);
+
+// Deprecated alias to Py_fopen() kept for backward compatibility
+Py_DEPRECATED(3.14) PyAPI_FUNC(FILE*) _Py_fopen_obj(
+ PyObject *path,
+ const char *mode);
+
+PyAPI_FUNC(int) Py_fclose(FILE *file);
diff --git a/Lib/test/test_capi/test_file.py b/Lib/test/test_capi/test_file.py
new file mode 100644
index 00000000000000..8a08a0a93eb8b7
--- /dev/null
+++ b/Lib/test/test_capi/test_file.py
@@ -0,0 +1,67 @@
+import os
+import unittest
+from test import support
+from test.support import import_helper, os_helper
+
+_testcapi = import_helper.import_module('_testcapi')
+
+
+class CAPIFileTest(unittest.TestCase):
+ def test_py_fopen(self):
+ # Test Py_fopen() and Py_fclose()
+
+ with open(__file__, "rb") as fp:
+ source = fp.read()
+
+ for filename in (__file__, os.fsencode(__file__)):
+ with self.subTest(filename=filename):
+ data = _testcapi.py_fopen(filename, "rb")
+ self.assertEqual(data, source[:256])
+
+ data = _testcapi.py_fopen(os_helper.FakePath(filename), "rb")
+ self.assertEqual(data, source[:256])
+
+ filenames = [
+ os_helper.TESTFN,
+ os.fsencode(os_helper.TESTFN),
+ ]
+ # TESTFN_UNDECODABLE cannot be used to create a file on macOS/WASI.
+ if os_helper.TESTFN_UNENCODABLE is not None:
+ filenames.append(os_helper.TESTFN_UNENCODABLE)
+ for filename in filenames:
+ with self.subTest(filename=filename):
+ try:
+ with open(filename, "wb") as fp:
+ fp.write(source)
+
+ data = _testcapi.py_fopen(filename, "rb")
+ self.assertEqual(data, source[:256])
+ finally:
+ os_helper.unlink(filename)
+
+ # embedded null character/byte in the filename
+ with self.assertRaises(ValueError):
+ _testcapi.py_fopen("a\x00b", "rb")
+ with self.assertRaises(ValueError):
+ _testcapi.py_fopen(b"a\x00b", "rb")
+
+ # non-ASCII mode failing with "Invalid argument"
+ with self.assertRaises(OSError):
+ _testcapi.py_fopen(__file__, "\xe9")
+
+ # invalid filename type
+ for invalid_type in (123, object()):
+ with self.subTest(filename=invalid_type):
+ with self.assertRaises(TypeError):
+ _testcapi.py_fopen(invalid_type, "rb")
+
+ if support.MS_WINDOWS:
+ with self.assertRaises(OSError):
+ # On Windows, the file mode is limited to 10 characters
+ _testcapi.py_fopen(__file__, "rt+, ccs=UTF-8")
+
+ # CRASHES py_fopen(__file__, None)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index c16ef3f96f9a21..9863f3ffe97656 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -1325,8 +1325,7 @@ def test_load_verify_cadata(self):
def test_load_dh_params(self):
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_dh_params(DHFILE)
- if os.name != 'nt':
- ctx.load_dh_params(BYTES_DHFILE)
+ ctx.load_dh_params(BYTES_DHFILE)
self.assertRaises(TypeError, ctx.load_dh_params)
self.assertRaises(TypeError, ctx.load_dh_params, None)
with self.assertRaises(FileNotFoundError) as cm:
diff --git a/Misc/NEWS.d/next/C_API/2024-12-11-13-01-26.gh-issue-127350.uEBZZ4.rst b/Misc/NEWS.d/next/C_API/2024-12-11-13-01-26.gh-issue-127350.uEBZZ4.rst
new file mode 100644
index 00000000000000..d1b528c673442f
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2024-12-11-13-01-26.gh-issue-127350.uEBZZ4.rst
@@ -0,0 +1,5 @@
+Add :c:func:`Py_fopen` function to open a file. Similar to the :c:func:`!fopen`
+function, but the *path* parameter is a Python object and an exception is set
+on error. Add also :c:func:`Py_fclose` function to close a file, function
+needed for Windows support.
+Patch by Victor Stinner.
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 74cf99957389e2..87739832fbf784 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -4377,7 +4377,7 @@ _ssl__SSLContext_load_dh_params_impl(PySSLContext *self, PyObject *filepath)
FILE *f;
DH *dh;
- f = _Py_fopen_obj(filepath, "rb");
+ f = Py_fopen(filepath, "rb");
if (f == NULL)
return NULL;
diff --git a/Modules/_ssl/debughelpers.c b/Modules/_ssl/debughelpers.c
index 9c87f8b4d21e68..318c045a0eec3c 100644
--- a/Modules/_ssl/debughelpers.c
+++ b/Modules/_ssl/debughelpers.c
@@ -180,8 +180,8 @@ _PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) {
return 0;
}
- /* _Py_fopen_obj() also checks that arg is of proper type. */
- fp = _Py_fopen_obj(arg, "a" PY_STDIOTEXTMODE);
+ /* Py_fopen() also checks that arg is of proper type. */
+ fp = Py_fopen(arg, "a" PY_STDIOTEXTMODE);
if (fp == NULL)
return -1;
diff --git a/Modules/_testcapi/clinic/file.c.h b/Modules/_testcapi/clinic/file.c.h
new file mode 100644
index 00000000000000..2ca21fffcef680
--- /dev/null
+++ b/Modules/_testcapi/clinic/file.c.h
@@ -0,0 +1,48 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#include "pycore_modsupport.h" // _PyArg_CheckPositional()
+
+PyDoc_STRVAR(_testcapi_py_fopen__doc__,
+"py_fopen($module, path, mode, /)\n"
+"--\n"
+"\n"
+"Call Py_fopen(), fread(256) and Py_fclose(). Return read bytes.");
+
+#define _TESTCAPI_PY_FOPEN_METHODDEF \
+ {"py_fopen", _PyCFunction_CAST(_testcapi_py_fopen), METH_FASTCALL, _testcapi_py_fopen__doc__},
+
+static PyObject *
+_testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode);
+
+static PyObject *
+_testcapi_py_fopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ PyObject *path;
+ const char *mode;
+
+ if (!_PyArg_CheckPositional("py_fopen", nargs, 2, 2)) {
+ goto exit;
+ }
+ path = args[0];
+ if (!PyUnicode_Check(args[1])) {
+ _PyArg_BadArgument("py_fopen", "argument 2", "str", args[1]);
+ goto exit;
+ }
+ Py_ssize_t mode_length;
+ mode = PyUnicode_AsUTF8AndSize(args[1], &mode_length);
+ if (mode == NULL) {
+ goto exit;
+ }
+ if (strlen(mode) != (size_t)mode_length) {
+ PyErr_SetString(PyExc_ValueError, "embedded null character");
+ goto exit;
+ }
+ return_value = _testcapi_py_fopen_impl(module, path, mode);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: output=c9fe964c3e5a0c32 input=a9049054013a1b77]*/
diff --git a/Modules/_testcapi/file.c b/Modules/_testcapi/file.c
index 634563f6ea12cb..4bad43010fd440 100644
--- a/Modules/_testcapi/file.c
+++ b/Modules/_testcapi/file.c
@@ -1,8 +1,43 @@
+// clinic/file.c.h uses internal pycore_modsupport.h API
+#define PYTESTCAPI_NEED_INTERNAL_API
+
#include "parts.h"
#include "util.h"
+#include "clinic/file.c.h"
+
+/*[clinic input]
+module _testcapi
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/
+
+/*[clinic input]
+_testcapi.py_fopen
+
+ path: object
+ mode: str
+ /
+
+Call Py_fopen(), fread(256) and Py_fclose(). Return read bytes.
+[clinic start generated code]*/
+static PyObject *
+_testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode)
+/*[clinic end generated code: output=5a900af000f759de input=d7e7b8f0fd151953]*/
+{
+ FILE *fp = Py_fopen(path, mode);
+ if (fp == NULL) {
+ return NULL;
+ }
+
+ char buffer[256];
+ size_t size = fread(buffer, 1, Py_ARRAY_LENGTH(buffer), fp);
+ Py_fclose(fp);
+
+ return PyBytes_FromStringAndSize(buffer, size);
+}
static PyMethodDef test_methods[] = {
+ _TESTCAPI_PY_FOPEN_METHODDEF
{NULL},
};
diff --git a/Modules/_testcapi/object.c b/Modules/_testcapi/object.c
index 3af5429ef00985..841410c52b3ce2 100644
--- a/Modules/_testcapi/object.c
+++ b/Modules/_testcapi/object.c
@@ -15,7 +15,7 @@ call_pyobject_print(PyObject *self, PyObject * args)
return NULL;
}
- fp = _Py_fopen_obj(filename, "w+");
+ fp = Py_fopen(filename, "w+");
if (Py_IsTrue(print_raw)) {
flags = Py_PRINT_RAW;
@@ -41,7 +41,7 @@ pyobject_print_null(PyObject *self, PyObject *args)
return NULL;
}
- fp = _Py_fopen_obj(filename, "w+");
+ fp = Py_fopen(filename, "w+");
if (PyObject_Print(NULL, fp, 0) < 0) {
fclose(fp);
@@ -72,7 +72,7 @@ pyobject_print_noref_object(PyObject *self, PyObject *args)
return NULL;
}
- fp = _Py_fopen_obj(filename, "w+");
+ fp = Py_fopen(filename, "w+");
if (PyObject_Print(test_string, fp, 0) < 0){
fclose(fp);
@@ -103,7 +103,7 @@ pyobject_print_os_error(PyObject *self, PyObject *args)
}
// open file in read mode to induce OSError
- fp = _Py_fopen_obj(filename, "r");
+ fp = Py_fopen(filename, "r");
if (PyObject_Print(test_string, fp, 0) < 0) {
fclose(fp);
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index f737250ac29d57..cd9014118f2d7f 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -1744,7 +1744,7 @@ pymarshal_write_long_to_file(PyObject* self, PyObject *args)
&value, &filename, &version))
return NULL;
- fp = _Py_fopen_obj(filename, "wb");
+ fp = Py_fopen(filename, "wb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -1769,7 +1769,7 @@ pymarshal_write_object_to_file(PyObject* self, PyObject *args)
&obj, &filename, &version))
return NULL;
- fp = _Py_fopen_obj(filename, "wb");
+ fp = Py_fopen(filename, "wb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -1793,7 +1793,7 @@ pymarshal_read_short_from_file(PyObject* self, PyObject *args)
if (!PyArg_ParseTuple(args, "O:pymarshal_read_short_from_file", &filename))
return NULL;
- fp = _Py_fopen_obj(filename, "rb");
+ fp = Py_fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -1818,7 +1818,7 @@ pymarshal_read_long_from_file(PyObject* self, PyObject *args)
if (!PyArg_ParseTuple(args, "O:pymarshal_read_long_from_file", &filename))
return NULL;
- fp = _Py_fopen_obj(filename, "rb");
+ fp = Py_fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -1840,7 +1840,7 @@ pymarshal_read_last_object_from_file(PyObject* self, PyObject *args)
if (!PyArg_ParseTuple(args, "O:pymarshal_read_last_object_from_file", &filename))
return NULL;
- FILE *fp = _Py_fopen_obj(filename, "rb");
+ FILE *fp = Py_fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -1863,7 +1863,7 @@ pymarshal_read_object_from_file(PyObject* self, PyObject *args)
if (!PyArg_ParseTuple(args, "O:pymarshal_read_object_from_file", &filename))
return NULL;
- FILE *fp = _Py_fopen_obj(filename, "rb");
+ FILE *fp = Py_fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
diff --git a/Modules/main.c b/Modules/main.c
index 3bf2241f2837a3..5bb1de2d04d30c 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -370,7 +370,7 @@ pymain_run_file_obj(PyObject *program_name, PyObject *filename,
return pymain_exit_err_print();
}
- FILE *fp = _Py_fopen_obj(filename, "rb");
+ FILE *fp = Py_fopen(filename, "rb");
if (fp == NULL) {
// Ignore the OSError
PyErr_Clear();
@@ -465,7 +465,7 @@ pymain_run_startup(PyConfig *config, int *exitcode)
goto error;
}
- FILE *fp = _Py_fopen_obj(startup, "r");
+ FILE *fp = Py_fopen(startup, "r");
if (fp == NULL) {
int save_errno = errno;
PyErr_Clear();
diff --git a/Python/errors.c b/Python/errors.c
index 2d362c1864ffff..b6ac2f767a283b 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -1981,7 +1981,7 @@ _PyErr_ProgramDecodedTextObject(PyObject *filename, int lineno, const char* enco
return NULL;
}
- FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE);
+ FILE *fp = Py_fopen(filename, "r" PY_STDIOTEXTMODE);
if (fp == NULL) {
PyErr_Clear();
return NULL;
diff --git a/Python/fileutils.c b/Python/fileutils.c
index 81276651f6df44..6bc3a44c3c1313 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -1748,8 +1748,10 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode)
}
-/* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem
- encoding and call fopen() otherwise.
+/* Open a file.
+
+ On Windows, if 'path' is a Unicode string, call _wfopen(). Otherwise, encode
+ the path to the filesystem encoding and call fopen().
Return the new file object on success. Raise an exception and return NULL
on error.
@@ -1762,32 +1764,32 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode)
Release the GIL to call _wfopen() or fopen(). The caller must hold
the GIL. */
FILE*
-_Py_fopen_obj(PyObject *path, const char *mode)
+Py_fopen(PyObject *path, const char *mode)
{
- FILE *f;
- int async_err = 0;
-#ifdef MS_WINDOWS
- wchar_t wmode[10];
- int usize;
-
assert(PyGILState_Check());
if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
return NULL;
}
- if (!PyUnicode_Check(path)) {
- PyErr_Format(PyExc_TypeError,
- "str file path expected under Windows, got %R",
- Py_TYPE(path));
+
+ FILE *f;
+ int async_err = 0;
+ int saved_errno;
+#ifdef MS_WINDOWS
+ PyObject *unicode;
+ if (!PyUnicode_FSDecoder(path, &unicode)) {
return NULL;
}
- wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL);
- if (wpath == NULL)
+ wchar_t *wpath = PyUnicode_AsWideCharString(unicode, NULL);
+ Py_DECREF(unicode);
+ if (wpath == NULL) {
return NULL;
+ }
- usize = MultiByteToWideChar(CP_ACP, 0, mode, -1,
- wmode, Py_ARRAY_LENGTH(wmode));
+ wchar_t wmode[10];
+ int usize = MultiByteToWideChar(CP_ACP, 0, mode, -1,
+ wmode, Py_ARRAY_LENGTH(wmode));
if (usize == 0) {
PyErr_SetFromWindowsErr(0);
PyMem_Free(wpath);
@@ -1796,26 +1798,20 @@ _Py_fopen_obj(PyObject *path, const char *mode)
do {
Py_BEGIN_ALLOW_THREADS
+ _Py_BEGIN_SUPPRESS_IPH
f = _wfopen(wpath, wmode);
+ _Py_END_SUPPRESS_IPH
Py_END_ALLOW_THREADS
} while (f == NULL
&& errno == EINTR && !(async_err = PyErr_CheckSignals()));
- int saved_errno = errno;
+ saved_errno = errno;
PyMem_Free(wpath);
#else
PyObject *bytes;
- const char *path_bytes;
-
- assert(PyGILState_Check());
-
- if (!PyUnicode_FSConverter(path, &bytes))
- return NULL;
- path_bytes = PyBytes_AS_STRING(bytes);
-
- if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
- Py_DECREF(bytes);
+ if (!PyUnicode_FSConverter(path, &bytes)) {
return NULL;
}
+ const char *path_bytes = PyBytes_AS_STRING(bytes);
do {
Py_BEGIN_ALLOW_THREADS
@@ -1823,11 +1819,13 @@ _Py_fopen_obj(PyObject *path, const char *mode)
Py_END_ALLOW_THREADS
} while (f == NULL
&& errno == EINTR && !(async_err = PyErr_CheckSignals()));
- int saved_errno = errno;
+ saved_errno = errno;
Py_DECREF(bytes);
#endif
- if (async_err)
+
+ if (async_err) {
return NULL;
+ }
if (f == NULL) {
errno = saved_errno;
@@ -1842,6 +1840,27 @@ _Py_fopen_obj(PyObject *path, const char *mode)
return f;
}
+
+// Deprecated alias to Py_fopen() kept for backward compatibility
+FILE*
+_Py_fopen_obj(PyObject *path, const char *mode)
+{
+ return Py_fopen(path, mode);
+}
+
+
+// Call fclose().
+//
+// On Windows, files opened by Py_fopen() in the Python DLL must be closed by
+// the Python DLL to use the same C runtime version. Otherwise, calling
+// fclose() directly can cause undefined behavior.
+int
+Py_fclose(FILE *file)
+{
+ return fclose(file);
+}
+
+
/* Read count bytes from fd into buf.
On success, return the number of read bytes, it can be lower than count.
diff --git a/Python/import.c b/Python/import.c
index a9282dde633959..b3648e24d0e064 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -4688,7 +4688,7 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
* code relies on fp still being open. */
FILE *fp;
if (file != NULL) {
- fp = _Py_fopen_obj(info.filename, "r");
+ fp = Py_fopen(info.filename, "r");
if (fp == NULL) {
goto finally;
}
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 31e065ff00d59a..0da26ad3f9b4bd 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -467,7 +467,7 @@ _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit,
fclose(fp);
}
- pyc_fp = _Py_fopen_obj(filename, "rb");
+ pyc_fp = Py_fopen(filename, "rb");
if (pyc_fp == NULL) {
fprintf(stderr, "python: Can't reopen .pyc file\n");
goto done;
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index d6719f9bb0af91..887591a681b25c 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -2356,7 +2356,7 @@ static PyObject *
sys__dump_tracelets_impl(PyObject *module, PyObject *outpath)
/*[clinic end generated code: output=a7fe265e2bc3b674 input=5bff6880cd28ffd1]*/
{
- FILE *out = _Py_fopen_obj(outpath, "wb");
+ FILE *out = Py_fopen(outpath, "wb");
if (out == NULL) {
return NULL;
}
1
0
gh-128340: add thread safe handle for `loop.call_soon_threadsafe` (#128369)
by kumaraditya303 06 Jan '25
by kumaraditya303 06 Jan '25
06 Jan '25
https://github.com/python/cpython/commit/7e8c571604cd18e65cefd26bfc48082840…
commit: 7e8c571604cd18e65cefd26bfc48082840264549
branch: main
author: Kumar Aditya <kumaraditya(a)python.org>
committer: kumaraditya303 <kumaraditya(a)python.org>
date: 2025-01-06T18:05:11+05:30
summary:
gh-128340: add thread safe handle for `loop.call_soon_threadsafe` (#128369)
Adds `_ThreadSafeHandle` to be used for callbacks scheduled with `loop.call_soon_threadsafe`.
files:
A Misc/NEWS.d/next/Library/2025-01-05-11-46-14.gh-issue-128340.gKI0uU.rst
M Lib/asyncio/base_events.py
M Lib/asyncio/events.py
M Lib/test/test_asyncio/test_events.py
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 5dbe4b28d236d3..9e6f6e3ee7e3ec 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -873,7 +873,10 @@ def call_soon_threadsafe(self, callback, *args, context=None):
self._check_closed()
if self._debug:
self._check_callback(callback, 'call_soon_threadsafe')
- handle = self._call_soon(callback, args, context)
+ handle = events._ThreadSafeHandle(callback, args, self, context)
+ self._ready.append(handle)
+ if handle._source_traceback:
+ del handle._source_traceback[-1]
if handle._source_traceback:
del handle._source_traceback[-1]
self._write_to_self()
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index 6e291d28ec81ae..2ee9870e80f20b 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -113,6 +113,34 @@ def _run(self):
self._loop.call_exception_handler(context)
self = None # Needed to break cycles when an exception occurs.
+# _ThreadSafeHandle is used for callbacks scheduled with call_soon_threadsafe
+# and is thread safe unlike Handle which is not thread safe.
+class _ThreadSafeHandle(Handle):
+
+ __slots__ = ('_lock',)
+
+ def __init__(self, callback, args, loop, context=None):
+ super().__init__(callback, args, loop, context)
+ self._lock = threading.RLock()
+
+ def cancel(self):
+ with self._lock:
+ return super().cancel()
+
+ def cancelled(self):
+ with self._lock:
+ return super().cancelled()
+
+ def _run(self):
+ # The event loop checks for cancellation without holding the lock
+ # It is possible that the handle is cancelled after the check
+ # but before the callback is called so check it again after acquiring
+ # the lock and return without calling the callback if it is cancelled.
+ with self._lock:
+ if self._cancelled:
+ return
+ return super()._run()
+
class TimerHandle(Handle):
"""Object returned by timed callback registration methods."""
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index c8439c9af5e6ba..ed75b909317357 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -353,6 +353,124 @@ def run_in_thread():
t.join()
self.assertEqual(results, ['hello', 'world'])
+ def test_call_soon_threadsafe_handle_block_check_cancelled(self):
+ results = []
+
+ callback_started = threading.Event()
+ callback_finished = threading.Event()
+ def callback(arg):
+ callback_started.set()
+ results.append(arg)
+ time.sleep(1)
+ callback_finished.set()
+
+ def run_in_thread():
+ handle = self.loop.call_soon_threadsafe(callback, 'hello')
+ self.assertIsInstance(handle, events._ThreadSafeHandle)
+ callback_started.wait()
+ # callback started so it should block checking for cancellation
+ # until it finishes
+ self.assertFalse(handle.cancelled())
+ self.assertTrue(callback_finished.is_set())
+ self.loop.call_soon_threadsafe(self.loop.stop)
+
+ t = threading.Thread(target=run_in_thread)
+ t.start()
+
+ self.loop.run_forever()
+ t.join()
+ self.assertEqual(results, ['hello'])
+
+ def test_call_soon_threadsafe_handle_block_cancellation(self):
+ results = []
+
+ callback_started = threading.Event()
+ callback_finished = threading.Event()
+ def callback(arg):
+ callback_started.set()
+ results.append(arg)
+ time.sleep(1)
+ callback_finished.set()
+
+ def run_in_thread():
+ handle = self.loop.call_soon_threadsafe(callback, 'hello')
+ self.assertIsInstance(handle, events._ThreadSafeHandle)
+ callback_started.wait()
+ # callback started so it cannot be cancelled from other thread until
+ # it finishes
+ handle.cancel()
+ self.assertTrue(callback_finished.is_set())
+ self.loop.call_soon_threadsafe(self.loop.stop)
+
+ t = threading.Thread(target=run_in_thread)
+ t.start()
+
+ self.loop.run_forever()
+ t.join()
+ self.assertEqual(results, ['hello'])
+
+ def test_call_soon_threadsafe_handle_cancel_same_thread(self):
+ results = []
+ callback_started = threading.Event()
+ callback_finished = threading.Event()
+
+ fut = concurrent.futures.Future()
+ def callback(arg):
+ callback_started.set()
+ handle = fut.result()
+ handle.cancel()
+ results.append(arg)
+ callback_finished.set()
+ self.loop.stop()
+
+ def run_in_thread():
+ handle = self.loop.call_soon_threadsafe(callback, 'hello')
+ fut.set_result(handle)
+ self.assertIsInstance(handle, events._ThreadSafeHandle)
+ callback_started.wait()
+ # callback cancels itself from same thread so it has no effect
+ # it runs to completion
+ self.assertTrue(handle.cancelled())
+ self.assertTrue(callback_finished.is_set())
+ self.loop.call_soon_threadsafe(self.loop.stop)
+
+ t = threading.Thread(target=run_in_thread)
+ t.start()
+
+ self.loop.run_forever()
+ t.join()
+ self.assertEqual(results, ['hello'])
+
+ def test_call_soon_threadsafe_handle_cancel_other_thread(self):
+ results = []
+ ev = threading.Event()
+
+ callback_finished = threading.Event()
+ def callback(arg):
+ results.append(arg)
+ callback_finished.set()
+ self.loop.stop()
+
+ def run_in_thread():
+ handle = self.loop.call_soon_threadsafe(callback, 'hello')
+ # handle can be cancelled from other thread if not started yet
+ self.assertIsInstance(handle, events._ThreadSafeHandle)
+ handle.cancel()
+ self.assertTrue(handle.cancelled())
+ self.assertFalse(callback_finished.is_set())
+ ev.set()
+ self.loop.call_soon_threadsafe(self.loop.stop)
+
+ # block the main loop until the callback is added and cancelled in the
+ # other thread
+ self.loop.call_soon(ev.wait)
+ t = threading.Thread(target=run_in_thread)
+ t.start()
+ self.loop.run_forever()
+ t.join()
+ self.assertEqual(results, [])
+ self.assertFalse(callback_finished.is_set())
+
def test_call_soon_threadsafe_same_thread(self):
results = []
diff --git a/Misc/NEWS.d/next/Library/2025-01-05-11-46-14.gh-issue-128340.gKI0uU.rst b/Misc/NEWS.d/next/Library/2025-01-05-11-46-14.gh-issue-128340.gKI0uU.rst
new file mode 100644
index 00000000000000..790400a19f334b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-01-05-11-46-14.gh-issue-128340.gKI0uU.rst
@@ -0,0 +1 @@
+Add internal thread safe handle to be used in :meth:`asyncio.loop.call_soon_threadsafe` for thread safe cancellation.
1
0
gh-90241: Clarify documentation for PyUnicode_FSConverter and PyUnicode_FSDecoder (GH-128451)
by encukou 06 Jan '25
by encukou 06 Jan '25
06 Jan '25
https://github.com/python/cpython/commit/657d7b77e5c69967e9c0000b986fa4872d…
commit: 657d7b77e5c69967e9c0000b986fa4872d13958c
branch: main
author: Serhiy Storchaka <storchaka(a)gmail.com>
committer: encukou <encukou(a)gmail.com>
date: 2025-01-06T13:28:50+01:00
summary:
gh-90241: Clarify documentation for PyUnicode_FSConverter and PyUnicode_FSDecoder (GH-128451)
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland(a)users.noreply.github.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland(a)protonmail.com>
files:
M Doc/c-api/arg.rst
M Doc/c-api/unicode.rst
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 41c0366d205086..209056ef2f8bce 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -319,7 +319,7 @@ Other objects
.. _o_ampersand:
-``O&`` (object) [*converter*, *anything*]
+``O&`` (object) [*converter*, *address*]
Convert a Python object to a C variable through a *converter* function. This
takes two arguments: the first is a function, the second is the address of a C
variable (of arbitrary type), converted to :c:expr:`void *`. The *converter*
@@ -333,14 +333,20 @@ Other objects
the conversion has failed. When the conversion fails, the *converter* function
should raise an exception and leave the content of *address* unmodified.
- If the *converter* returns ``Py_CLEANUP_SUPPORTED``, it may get called a
+ .. c:macro:: Py_CLEANUP_SUPPORTED
+ :no-typesetting:
+
+ If the *converter* returns :c:macro:`!Py_CLEANUP_SUPPORTED`, it may get called a
second time if the argument parsing eventually fails, giving the converter a
chance to release any memory that it had already allocated. In this second
call, the *object* parameter will be ``NULL``; *address* will have the same value
as in the original call.
+ Examples of converters: :c:func:`PyUnicode_FSConverter` and
+ :c:func:`PyUnicode_FSDecoder`.
+
.. versionchanged:: 3.1
- ``Py_CLEANUP_SUPPORTED`` was added.
+ :c:macro:`!Py_CLEANUP_SUPPORTED` was added.
``p`` (:class:`bool`) [int]
Tests the value passed in for truth (a boolean **p**\ redicate) and converts
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index dcbc8804cd6b89..f19b86a8dbfb66 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -786,16 +786,25 @@ Functions encoding to and decoding from the :term:`filesystem encoding and
error handler` (:pep:`383` and :pep:`529`).
To encode file names to :class:`bytes` during argument parsing, the ``"O&"``
-converter should be used, passing :c:func:`PyUnicode_FSConverter` as the
+converter should be used, passing :c:func:`!PyUnicode_FSConverter` as the
conversion function:
.. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result)
- ParseTuple converter: encode :class:`str` objects -- obtained directly or
+ :ref:`PyArg_Parse\* converter <arg-parsing>`: encode :class:`str` objects -- obtained directly or
through the :class:`os.PathLike` interface -- to :class:`bytes` using
:c:func:`PyUnicode_EncodeFSDefault`; :class:`bytes` objects are output as-is.
- *result* must be a :c:expr:`PyBytesObject*` which must be released when it is
- no longer used.
+ *result* must be an address of a C variable of type :c:expr:`PyObject*`
+ (or :c:expr:`PyBytesObject*`).
+ On success, set the variable to a new :term:`strong reference` to
+ a :ref:`bytes object <bytesobjects>` which must be released
+ when it is no longer used and return a non-zero value
+ (:c:macro:`Py_CLEANUP_SUPPORTED`).
+ Embedded null bytes are not allowed in the result.
+ On failure, return ``0`` with an exception set.
+
+ If *obj* is ``NULL``, the function releases a strong reference
+ stored in the variable referred by *result* and returns ``1``.
.. versionadded:: 3.1
@@ -803,16 +812,26 @@ conversion function:
Accepts a :term:`path-like object`.
To decode file names to :class:`str` during argument parsing, the ``"O&"``
-converter should be used, passing :c:func:`PyUnicode_FSDecoder` as the
+converter should be used, passing :c:func:`!PyUnicode_FSDecoder` as the
conversion function:
.. c:function:: int PyUnicode_FSDecoder(PyObject* obj, void* result)
- ParseTuple converter: decode :class:`bytes` objects -- obtained either
+ :ref:`PyArg_Parse\* converter <arg-parsing>`: decode :class:`bytes` objects -- obtained either
directly or indirectly through the :class:`os.PathLike` interface -- to
:class:`str` using :c:func:`PyUnicode_DecodeFSDefaultAndSize`; :class:`str`
- objects are output as-is. *result* must be a :c:expr:`PyUnicodeObject*` which
- must be released when it is no longer used.
+ objects are output as-is.
+ *result* must be an address of a C variable of type :c:expr:`PyObject*`
+ (or :c:expr:`PyUnicodeObject*`).
+ On success, set the variable to a new :term:`strong reference` to
+ a :ref:`Unicode object <unicodeobjects>` which must be released
+ when it is no longer used and return a non-zero value
+ (:c:macro:`Py_CLEANUP_SUPPORTED`).
+ Embedded null characters are not allowed in the result.
+ On failure, return ``0`` with an exception set.
+
+ If *obj* is ``NULL``, release the strong reference
+ to the object referred to by *result* and return ``1``.
.. versionadded:: 3.2
1
0
06 Jan '25
https://github.com/python/cpython/commit/1ef6bf4e29db43bbf06639923516838db2…
commit: 1ef6bf4e29db43bbf06639923516838db2d5a5ba
branch: main
author: Bénédikt Tran <10796600+picnixz(a)users.noreply.github.com>
committer: encukou <encukou(a)gmail.com>
date: 2025-01-06T12:50:01+01:00
summary:
gh-111178: fix UBSan failures in `Objects/descrobject.c` (GH-128245)
fix UBSan failures for `propertyobject`
files:
M Objects/descrobject.c
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 4eccd1704eb95a..1852118359f014 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -1508,6 +1508,8 @@ PyWrapper_New(PyObject *d, PyObject *self)
/* A built-in 'property' type */
+#define _propertyobject_CAST(op) ((propertyobject *)(op))
+
/*
class property(object):
@@ -1911,8 +1913,9 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
}
static PyObject *
-property_get__name__(propertyobject *prop, void *Py_UNUSED(ignored))
+property_get__name__(PyObject *op, void *Py_UNUSED(ignored))
{
+ propertyobject *prop = _propertyobject_CAST(op);
PyObject *name;
if (property_name(prop, &name) < 0) {
return NULL;
@@ -1925,16 +1928,17 @@ property_get__name__(propertyobject *prop, void *Py_UNUSED(ignored))
}
static int
-property_set__name__(propertyobject *prop, PyObject *value,
- void *Py_UNUSED(ignored))
+property_set__name__(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
{
+ propertyobject *prop = _propertyobject_CAST(op);
Py_XSETREF(prop->prop_name, Py_XNewRef(value));
return 0;
}
static PyObject *
-property_get___isabstractmethod__(propertyobject *prop, void *closure)
+property_get___isabstractmethod__(PyObject *op, void *closure)
{
+ propertyobject *prop = _propertyobject_CAST(op);
int res = _PyObject_IsAbstract(prop->prop_get);
if (res == -1) {
return NULL;
@@ -1962,9 +1966,8 @@ property_get___isabstractmethod__(propertyobject *prop, void *closure)
}
static PyGetSetDef property_getsetlist[] = {
- {"__name__", (getter)property_get__name__, (setter)property_set__name__},
- {"__isabstractmethod__",
- (getter)property_get___isabstractmethod__, NULL,
+ {"__name__", property_get__name__, property_set__name__, NULL, NULL},
+ {"__isabstractmethod__", property_get___isabstractmethod__, NULL,
NULL,
NULL},
{NULL} /* Sentinel */
1
0