summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_compile.py25
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2022-09-20-11-06-45.gh-issue-95921.dkcRQn.rst2
-rw-r--r--Python/compile.c1
3 files changed, 28 insertions, 0 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 3ed57c2..4b35cce 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1077,6 +1077,31 @@ if 1:
check_op_count(aug, "STORE_SLICE", 1)
check_op_count(aug, "BUILD_SLICE", 0)
+ 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):
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
index 0000000..0c8b704
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-09-20-11-06-45.gh-issue-95921.dkcRQn.rst
@@ -0,0 +1,2 @@
+Fix overly-broad source position information for chained comparisons used as
+branching conditions.
diff --git a/Python/compile.c b/Python/compile.c
index 1f1ef56..507fd04 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -2905,6 +2905,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label 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)) {