Skip to content

Commit aced809

Browse files
authored
[3.10] GH-95921: Fix positions for some chained comparisons (GH-96968) (GH-96974)
(cherry picked from commit dfc73b5) Automerge-Triggered-By: GH:brandtbucher
1 parent 21b5af9 commit aced809

File tree

6 files changed

+1666
-1632
lines changed

6 files changed

+1666
-1632
lines changed

Lib/test/test_compile.py

+32
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,38 @@ def if_else_break():
984984
elif instr.opname in HANDLED_JUMPS:
985985
self.assertNotEqual(instr.arg, (line + 1)*INSTR_SIZE)
986986

987+
def test_compare_positions(self):
988+
for opname, op in [
989+
("COMPARE_OP", "<"),
990+
("COMPARE_OP", "<="),
991+
("COMPARE_OP", ">"),
992+
("COMPARE_OP", ">="),
993+
("CONTAINS_OP", "in"),
994+
("CONTAINS_OP", "not in"),
995+
("IS_OP", "is"),
996+
("IS_OP", "is not"),
997+
]:
998+
expr = f'a {op} b {op} c'
999+
expected_lines = 2 * [2]
1000+
for source in [
1001+
f"\\\n{expr}", f'if \\\n{expr}: x', f"x if \\\n{expr} else y"
1002+
]:
1003+
code = compile(source, "<test>", "exec")
1004+
all_lines = (
1005+
line
1006+
for start, stop, line in code.co_lines()
1007+
for _ in range(start, stop, 2)
1008+
)
1009+
actual_lines = [
1010+
line
1011+
for instruction, line in zip(
1012+
dis.get_instructions(code), all_lines, strict=True
1013+
)
1014+
if instruction.opname == opname
1015+
]
1016+
with self.subTest(source):
1017+
self.assertEqual(actual_lines, expected_lines)
1018+
9871019

9881020
class TestExpressionStackSize(unittest.TestCase):
9891021
# These tests check that the computed stack size for a code object
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
@@ -2691,6 +2691,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
26912691
return 1;
26922692
}
26932693
case Compare_kind: {
2694+
SET_LOC(c, e);
26942695
Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1;
26952696
if (n > 0) {
26962697
if (!check_compare(c, e)) {

0 commit comments

Comments
 (0)