https://github.com/python/cpython/commit/0ccf244a197d7a5db216e8ed630089cefa370dd6
commit: 0ccf244a197d7a5db216e8ed630089cefa370dd6
branch: 3.14
author: Irit Katriel <[email protected]>
committer: hugovk <[email protected]>
date: 2025-08-12T12:56:37+03:00
summary:

[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]>

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-08-01-18-54-31.gh-issue-137288.FhE7ku.rst
M Include/internal/pycore_magic_number.h
M Lib/test/test_compile.py
M Lib/test/test_importlib/test_util.py
M Python/flowgraph.c

diff --git a/Include/internal/pycore_magic_number.h 
b/Include/internal/pycore_magic_number.h
index 95754025a4aa05..388b6b764faf41 100644
--- a/Include/internal/pycore_magic_number.h
+++ b/Include/internal/pycore_magic_number.h
@@ -278,6 +278,7 @@ Known values:
     Python 3.14a7 3623 (Add BUILD_INTERPOLATION & BUILD_TEMPLATE opcodes)
     Python 3.14b1 3624 (Don't optimize LOAD_FAST when local is killed by 
DELETE_FAST)
     Python 3.14b3 3625 (Fix handling of opcodes that may leave operands on the 
stack when optimizing LOAD_FAST)
+    Python 3.14b5 3626 (Fix missing exception handlers in logical expression)
 
     Python 3.15 will start with 3650
 
@@ -290,7 +291,7 @@ PC/launcher.c must also be updated.
 
 */
 
-#define PYC_MAGIC_NUMBER 3625
+#define PYC_MAGIC_NUMBER 3626
 /* 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/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 57e5f29b015637..8a66be9b331262 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1723,6 +1723,21 @@ def test_compound(self):
         self.assertIs(res, v[3])
         self.assertEqual([e.called for e in v], [1, 1, 0, 1, 0])
 
+    def test_exception(self):
+        # See gh-137288
+        class Foo:
+            def __bool__(self):
+                raise NotImplementedError()
+
+        a = Foo()
+        b = Foo()
+
+        with self.assertRaises(NotImplementedError):
+            bool(a)
+
+        with self.assertRaises(NotImplementedError):
+            c = a or b
+
 @requires_debug_ranges()
 class TestSourcePositions(unittest.TestCase):
     # Ensure that compiled code snippets have correct line and column numbers
diff --git a/Lib/test/test_importlib/test_util.py 
b/Lib/test/test_importlib/test_util.py
index 6d6d5f96aab4a8..1e87fcc8de3725 100644
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -635,7 +635,7 @@ def test_magic_number(self):
         # stakeholders such as OS package maintainers must be notified
         # in advance. Such exceptional releases will then require an
         # adjustment to this test case.
-        EXPECTED_MAGIC_NUMBER = 3625
+        EXPECTED_MAGIC_NUMBER = 3626
         actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little')
 
         msg = (
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-08-01-18-54-31.gh-issue-137288.FhE7ku.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-01-18-54-31.gh-issue-137288.FhE7ku.rst
new file mode 100644
index 00000000000000..37c143f18e76f7
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-01-18-54-31.gh-issue-137288.FhE7ku.rst
@@ -0,0 +1,2 @@
+Fix bug where some bytecode instructions of a boolean expression are not
+associated with the correct exception handler.
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index 8e395b14739d94..04cd7a003da963 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -3463,11 +3463,13 @@ convert_pseudo_conditional_jumps(cfg_builder *g)
                 instr->i_opcode = instr->i_opcode == JUMP_IF_FALSE ?
                                           POP_JUMP_IF_FALSE : POP_JUMP_IF_TRUE;
                 location loc = instr->i_loc;
+                basicblock *except = instr->i_except;
                 cfg_instr copy = {
                             .i_opcode = COPY,
                             .i_oparg = 1,
                             .i_loc = loc,
                             .i_target = NULL,
+                            .i_except = except,
                 };
                 RETURN_IF_ERROR(basicblock_insert_instruction(b, i++, &copy));
                 cfg_instr to_bool = {
@@ -3475,6 +3477,7 @@ convert_pseudo_conditional_jumps(cfg_builder *g)
                             .i_oparg = 0,
                             .i_loc = loc,
                             .i_target = NULL,
+                            .i_except = except,
                 };
                 RETURN_IF_ERROR(basicblock_insert_instruction(b, i++, 
&to_bool));
             }
@@ -3717,6 +3720,7 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata 
*umd, basicblock *entrybl
             .i_oparg = 0,
             .i_loc = loc,
             .i_target = NULL,
+            .i_except = NULL,
         };
         RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, 
&make_gen));
         cfg_instr pop_top = {
@@ -3724,6 +3728,7 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata 
*umd, basicblock *entrybl
             .i_oparg = 0,
             .i_loc = loc,
             .i_target = NULL,
+            .i_except = NULL,
         };
         RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 1, 
&pop_top));
     }
@@ -3754,6 +3759,7 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata 
*umd, basicblock *entrybl
                 .i_oparg = oldindex,
                 .i_loc = NO_LOCATION,
                 .i_target = NULL,
+                .i_except = NULL,
             };
             if (basicblock_insert_instruction(entryblock, ncellsused, 
&make_cell) < 0) {
                 PyMem_RawFree(sorted);
@@ -3770,6 +3776,7 @@ insert_prefix_instructions(_PyCompile_CodeUnitMetadata 
*umd, basicblock *entrybl
             .i_oparg = nfreevars,
             .i_loc = NO_LOCATION,
             .i_target = NULL,
+            .i_except = NULL,
         };
         RETURN_IF_ERROR(basicblock_insert_instruction(entryblock, 0, 
&copy_frees));
     }

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to