Skip to content

Commit dfc73b5

Browse files
authored
GH-95921: Fix positions for some chained comparisons (GH-96968)
1 parent 8563966 commit dfc73b5

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

Lib/test/test_compile.py

+25
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,31 @@ def aug():
10771077
check_op_count(aug, "STORE_SLICE", 1)
10781078
check_op_count(aug, "BUILD_SLICE", 0)
10791079

1080+
def test_compare_positions(self):
1081+
for opname, op in [
1082+
("COMPARE_OP", "<"),
1083+
("COMPARE_OP", "<="),
1084+
("COMPARE_OP", ">"),
1085+
("COMPARE_OP", ">="),
1086+
("CONTAINS_OP", "in"),
1087+
("CONTAINS_OP", "not in"),
1088+
("IS_OP", "is"),
1089+
("IS_OP", "is not"),
1090+
]:
1091+
expr = f'a {op} b {op} c'
1092+
expected_positions = 2 * [(2, 2, 0, len(expr))]
1093+
for source in [
1094+
f"\\\n{expr}", f'if \\\n{expr}: x', f"x if \\\n{expr} else y"
1095+
]:
1096+
code = compile(source, "<test>", "exec")
1097+
actual_positions = [
1098+
instruction.positions
1099+
for instruction in dis.get_instructions(code)
1100+
if instruction.opname == opname
1101+
]
1102+
with self.subTest(source):
1103+
self.assertEqual(actual_positions, expected_positions)
1104+
10801105

10811106
@requires_debug_ranges()
10821107
class TestSourcePositions(unittest.TestCase):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix overly-broad source position information for chained comparisons used as
2+
branching conditions.

Python/compile.c

+1
Original file line numberDiff line numberDiff line change
@@ -2905,6 +2905,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label next, int cond
29052905
return 1;
29062906
}
29072907
case Compare_kind: {
2908+
SET_LOC(c, e);
29082909
Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1;
29092910
if (n > 0) {
29102911
if (!check_compare(c, e)) {

0 commit comments

Comments
 (0)