]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] GH-95921: Fix positions for some chained comparisons (GH-96968) (GH-96973)
authorBrandt Bucher <brandtbucher@microsoft.com>
Tue, 20 Sep 2022 21:56:38 +0000 (14:56 -0700)
committerGitHub <noreply@github.com>
Tue, 20 Sep 2022 21:56:38 +0000 (14:56 -0700)
(cherry picked from commit dfc73b57247aac575c83055d960c03bdc28b51fd)

Automerge-Triggered-By: GH:brandtbucher
Lib/test/test_compile.py
Misc/NEWS.d/next/Core and Builtins/2022-09-20-11-06-45.gh-issue-95921.dkcRQn.rst [new file with mode: 0644]
Python/compile.c

index cd4d58acd4778e02ee919d2248a9c6b04f3f3f40..23f84b48fac830d31c197027ff33baef0781ded1 100644 (file)
@@ -1039,6 +1039,32 @@ if 1:
         for instr in dis.Bytecode(while_not_chained):
             self.assertNotEqual(instr.opname, "EXTENDED_ARG")
 
+    def test_compare_positions(self):
+        for opname, op in [
+            ("COMPARE_OP", "<"),
+            ("COMPARE_OP", "<="),
+            ("COMPARE_OP", ">"),
+            ("COMPARE_OP", ">="),
+            ("CONTAINS_OP", "in"),
+            ("CONTAINS_OP", "not in"),
+            ("IS_OP", "is"),
+            ("IS_OP", "is not"),
+        ]:
+            expr = f'a {op} b {op} c'
+            expected_positions = 2 * [(2, 2, 0, len(expr))]
+            for source in [
+                f"\\\n{expr}", f'if \\\n{expr}: x', f"x if \\\n{expr} else y"
+            ]:
+                code = compile(source, "<test>", "exec")
+                actual_positions = [
+                    instruction.positions
+                    for instruction in dis.get_instructions(code)
+                    if instruction.opname == opname
+                ]
+                with self.subTest(source):
+                    self.assertEqual(actual_positions, expected_positions)
+
+
 @requires_debug_ranges()
 class TestSourcePositions(unittest.TestCase):
     # Ensure that compiled code snippets have correct line and column numbers
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-09-20-11-06-45.gh-issue-95921.dkcRQn.rst b/Misc/NEWS.d/next/Core and Builtins/2022-09-20-11-06-45.gh-issue-95921.dkcRQn.rst
new file mode 100644 (file)
index 0000000..0c8b704
--- /dev/null
@@ -0,0 +1,2 @@
+Fix overly-broad source position information for chained comparisons used as
+branching conditions.
index 32fd58e6c4fd9d74ab7abaae7634d4aa65829c34..f4555b35ab95a19beaba4337713fd97a710c523f 100644 (file)
@@ -2930,6 +2930,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
         return 1;
     }
     case Compare_kind: {
+        SET_LOC(c, e);
         Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1;
         if (n > 0) {
             if (!check_compare(c, e)) {