Skip to content

Commit 0ccf244

Browse files
iritkatrielencukou
andauthored
[3.14] gh-137288: Fix bug where boolean expressions are not associated with the correct exception handler (GH-137310). (#137427)
Co-authored-by: Irit Katriel <[email protected]> Co-authored-by: Petr Viktorin <[email protected]>
1 parent 019238a commit 0ccf244

File tree

5 files changed

+27
-2
lines changed

5 files changed

+27
-2
lines changed

Include/internal/pycore_magic_number.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ Known values:
278278
Python 3.14a7 3623 (Add BUILD_INTERPOLATION & BUILD_TEMPLATE opcodes)
279279
Python 3.14b1 3624 (Don't optimize LOAD_FAST when local is killed by DELETE_FAST)
280280
Python 3.14b3 3625 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
281+
Python 3.14b5 3626 (Fix missing exception handlers in logical expression)
281282
282283
Python 3.15 will start with 3650
283284
@@ -290,7 +291,7 @@ PC/launcher.c must also be updated.
290291
291292
*/
292293

293-
#define PYC_MAGIC_NUMBER 3625
294+
#define PYC_MAGIC_NUMBER 3626
294295
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
295296
(little-endian) and then appending b'\r\n'. */
296297
#define PYC_MAGIC_NUMBER_TOKEN \

Lib/test/test_compile.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,21 @@ def test_compound(self):
17231723
self.assertIs(res, v[3])
17241724
self.assertEqual([e.called for e in v], [1, 1, 0, 1, 0])
17251725

1726+
def test_exception(self):
1727+
# See gh-137288
1728+
class Foo:
1729+
def __bool__(self):
1730+
raise NotImplementedError()
1731+
1732+
a = Foo()
1733+
b = Foo()
1734+
1735+
with self.assertRaises(NotImplementedError):
1736+
bool(a)
1737+
1738+
with self.assertRaises(NotImplementedError):
1739+
c = a or b
1740+
17261741
@requires_debug_ranges()
17271742
class TestSourcePositions(unittest.TestCase):
17281743
# Ensure that compiled code snippets have correct line and column numbers

Lib/test/test_importlib/test_util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ def test_magic_number(self):
635635
# stakeholders such as OS package maintainers must be notified
636636
# in advance. Such exceptional releases will then require an
637637
# adjustment to this test case.
638-
EXPECTED_MAGIC_NUMBER = 3625
638+
EXPECTED_MAGIC_NUMBER = 3626
639639
actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little')
640640

641641
msg = (
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix bug where some bytecode instructions of a boolean expression are not
2+
associated with the correct exception handler.

Python/flowgraph.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3463,18 +3463,21 @@ convert_pseudo_conditional_jumps(cfg_builder *g)
34633463
instr->i_opcode = instr->i_opcode == JUMP_IF_FALSE ?
34643464
POP_JUMP_IF_FALSE : POP_JUMP_IF_TRUE;
34653465
location loc = instr->i_loc;
3466+
basicblock *except = instr->i_except;
34663467
cfg_instr copy = {
34673468
.i_opcode = COPY,
34683469
.i_oparg = 1,
34693470
.i_loc = loc,
34703471
.i_target = NULL,
3472+
.i_except = except,
34713473
};
34723474
RETURN_IF_ERROR(basicblock_insert_instruction(b, i++, &copy));
34733475
cfg_instr to_bool = {
34743476
.i_opcode = TO_BOOL,
34753477
.i_oparg = 0,
34763478
.i_loc = loc,
34773479
.i_target = NULL,
3480+
.i_except = except,
34783481
};
34793482
RETURN_IF_ERROR(basicblock_insert_instruction(b, i++, &to_bool));
34803483
}
@@ -3717,13 +3720,15 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entrybl
37173720
.i_oparg = 0,
37183721
.i_loc = loc,
37193722
.i_target = NULL,
3723+
.i_except = NULL,
37203724
};
37213725
RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, &make_gen));
37223726
cfg_instr pop_top = {
37233727
.i_opcode = POP_TOP,
37243728
.i_oparg = 0,
37253729
.i_loc = loc,
37263730
.i_target = NULL,
3731+
.i_except = NULL,
37273732
};
37283733
RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 1, &pop_top));
37293734
}
@@ -3754,6 +3759,7 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entrybl
37543759
.i_oparg = oldindex,
37553760
.i_loc = NO_LOCATION,
37563761
.i_target = NULL,
3762+
.i_except = NULL,
37573763
};
37583764
if (basicblock_insert_instruction(entryblock, ncellsused, &make_cell) < 0) {
37593765
PyMem_RawFree(sorted);
@@ -3770,6 +3776,7 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entrybl
37703776
.i_oparg = nfreevars,
37713777
.i_loc = NO_LOCATION,
37723778
.i_target = NULL,
3779+
.i_except = NULL,
37733780
};
37743781
RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, &copy_frees));
37753782
}

0 commit comments

Comments
 (0)