Skip to content

Commit 1f2026b

Browse files
authored
gh-137288: Fix bug where boolean expressions are not associated with the correct exception handler (#137310)
1 parent 525784a commit 1f2026b

File tree

4 files changed

+26
-1
lines changed

4 files changed

+26
-1
lines changed

Include/internal/pycore_magic_number.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ Known values:
281281
Python 3.15a1 3651 (Simplify LOAD_CONST)
282282
Python 3.15a1 3652 (Virtual iterators)
283283
Python 3.15a1 3653 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
284+
Python 3.15a1 3654 (Fix missing exception handlers in logical expression)
284285
285286
286287
Python 3.16 will start with 3700
@@ -294,7 +295,7 @@ PC/launcher.c must also be updated.
294295
295296
*/
296297

297-
#define PYC_MAGIC_NUMBER 3653
298+
#define PYC_MAGIC_NUMBER 3654
298299
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
299300
(little-endian) and then appending b'\r\n'. */
300301
#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
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
@@ -3472,18 +3472,21 @@ convert_pseudo_conditional_jumps(cfg_builder *g)
34723472
instr->i_opcode = instr->i_opcode == JUMP_IF_FALSE ?
34733473
POP_JUMP_IF_FALSE : POP_JUMP_IF_TRUE;
34743474
location loc = instr->i_loc;
3475+
basicblock *except = instr->i_except;
34753476
cfg_instr copy = {
34763477
.i_opcode = COPY,
34773478
.i_oparg = 1,
34783479
.i_loc = loc,
34793480
.i_target = NULL,
3481+
.i_except = except,
34803482
};
34813483
RETURN_IF_ERROR(basicblock_insert_instruction(b, i++, &copy));
34823484
cfg_instr to_bool = {
34833485
.i_opcode = TO_BOOL,
34843486
.i_oparg = 0,
34853487
.i_loc = loc,
34863488
.i_target = NULL,
3489+
.i_except = except,
34873490
};
34883491
RETURN_IF_ERROR(basicblock_insert_instruction(b, i++, &to_bool));
34893492
}
@@ -3726,13 +3729,15 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entrybl
37263729
.i_oparg = 0,
37273730
.i_loc = loc,
37283731
.i_target = NULL,
3732+
.i_except = NULL,
37293733
};
37303734
RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, &make_gen));
37313735
cfg_instr pop_top = {
37323736
.i_opcode = POP_TOP,
37333737
.i_oparg = 0,
37343738
.i_loc = loc,
37353739
.i_target = NULL,
3740+
.i_except = NULL,
37363741
};
37373742
RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 1, &pop_top));
37383743
}
@@ -3763,6 +3768,7 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entrybl
37633768
.i_oparg = oldindex,
37643769
.i_loc = NO_LOCATION,
37653770
.i_target = NULL,
3771+
.i_except = NULL,
37663772
};
37673773
if (basicblock_insert_instruction(entryblock, ncellsused, &make_cell) < 0) {
37683774
PyMem_RawFree(sorted);
@@ -3779,6 +3785,7 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entrybl
37793785
.i_oparg = nfreevars,
37803786
.i_loc = NO_LOCATION,
37813787
.i_target = NULL,
3788+
.i_except = NULL,
37823789
};
37833790
RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, &copy_frees));
37843791
}

0 commit comments

Comments
 (0)