Skip to content

Commit 44f91fc

Browse files
authored
bpo-43950: use 0-indexed column offsets for bytecode positions (GH-27011)
1 parent d33943a commit 44f91fc

File tree

3 files changed

+19
-22
lines changed

3 files changed

+19
-22
lines changed

Lib/test/test_code.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ def test_co_positions_artificial_instructions(self):
344344
# get assigned the first_lineno but they don't have other positions.
345345
# There is no easy way of inferring them at that stage, so for now
346346
# we don't support it.
347-
self.assertTrue(all(positions) or not any(positions))
347+
self.assertTrue(positions.count(None) in [0, 4])
348348

349349
if not any(positions):
350350
artificial_instructions.append(instr)

Lib/test/test_compile.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,8 +1006,8 @@ def generic_visit(self, node):
10061006
return
10071007
lines.add(node.lineno)
10081008
end_lines.add(node.end_lineno)
1009-
columns.add(node.col_offset + 1)
1010-
end_columns.add(node.end_col_offset + 1)
1009+
columns.add(node.col_offset)
1010+
end_columns.add(node.end_col_offset)
10111011

10121012
SourceOffsetVisitor().visit(ast_tree)
10131013

@@ -1058,10 +1058,10 @@ def test_compiles_to_extended_op_arg(self):
10581058

10591059
self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_SUBTRACT',
10601060
line=10_000 + 2, end_line=10_000 + 2,
1061-
column=3, end_column=9)
1061+
column=2, end_column=8)
10621062
self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_ADD',
10631063
line=10_000 + 4, end_line=10_000 + 4,
1064-
column=3, end_column=10)
1064+
column=2, end_column=9)
10651065

10661066
def test_multiline_expression(self):
10671067
snippet = """\
@@ -1071,7 +1071,7 @@ def test_multiline_expression(self):
10711071
"""
10721072
compiled_code, _ = self.check_positions_against_ast(snippet)
10731073
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL_FUNCTION',
1074-
line=1, end_line=3, column=1, end_column=2)
1074+
line=1, end_line=3, column=0, end_column=1)
10751075

10761076
def test_very_long_line_end_offset(self):
10771077
# Make sure we get None for when the column offset is too large to
@@ -1088,15 +1088,15 @@ def test_complex_single_line_expression(self):
10881088

10891089
compiled_code, _ = self.check_positions_against_ast(snippet)
10901090
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_SUBSCR',
1091-
line=1, end_line=1, column=14, end_column=22)
1091+
line=1, end_line=1, column=13, end_column=21)
10921092
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_MULTIPLY',
1093-
line=1, end_line=1, column=10, end_column=22)
1093+
line=1, end_line=1, column=9, end_column=21)
10941094
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_ADD',
1095-
line=1, end_line=1, column=10, end_column=27)
1095+
line=1, end_line=1, column=9, end_column=26)
10961096
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_MATRIX_MULTIPLY',
1097-
line=1, end_line=1, column=5, end_column=28)
1097+
line=1, end_line=1, column=4, end_column=27)
10981098
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_SUBTRACT',
1099-
line=1, end_line=1, column=1, end_column=28)
1099+
line=1, end_line=1, column=0, end_column=27)
11001100

11011101

11021102
class TestExpressionStackSize(unittest.TestCase):

Objects/codeobject.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,6 @@ PyCode_Addr2Location(PyCodeObject *co, int addrq,
610610
int *end_line, int *end_column)
611611
{
612612
*start_line = PyCode_Addr2Line(co, addrq);
613-
if (*start_line == -1) {
614-
*start_line = 0;
615-
}
616613
*start_column = _PyCode_Addr2Offset(co, addrq);
617614
*end_line = _PyCode_Addr2EndLine(co, addrq);
618615
*end_column = _PyCode_Addr2EndOffset(co, addrq);
@@ -626,7 +623,7 @@ _PyCode_Addr2EndLine(PyCodeObject* co, int addrq)
626623
return co->co_firstlineno;
627624
}
628625
else if (co->co_endlinetable == Py_None) {
629-
return 0;
626+
return -1;
630627
}
631628

632629
assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code));
@@ -639,34 +636,34 @@ int
639636
_PyCode_Addr2Offset(PyCodeObject* co, int addrq)
640637
{
641638
if (co->co_columntable == Py_None || addrq < 0) {
642-
return 0;
639+
return -1;
643640
}
644641
if (addrq % 2 == 1) {
645642
--addrq;
646643
}
647644
if (addrq >= PyBytes_GET_SIZE(co->co_columntable)) {
648-
return 0;
645+
return -1;
649646
}
650647

651648
unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable);
652-
return bytes[addrq];
649+
return bytes[addrq] - 1;
653650
}
654651

655652
int
656653
_PyCode_Addr2EndOffset(PyCodeObject* co, int addrq)
657654
{
658655
if (co->co_columntable == Py_None || addrq < 0) {
659-
return 0;
656+
return -1;
660657
}
661658
if (addrq % 2 == 0) {
662659
++addrq;
663660
}
664661
if (addrq >= PyBytes_GET_SIZE(co->co_columntable)) {
665-
return 0;
662+
return -1;
666663
}
667664

668665
unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable);
669-
return bytes[addrq];
666+
return bytes[addrq] - 1;
670667
}
671668

672669
void
@@ -980,7 +977,7 @@ positionsiter_dealloc(positionsiterator* pi)
980977

981978
static PyObject*
982979
_source_offset_converter(int* value) {
983-
if (*value <= 0) {
980+
if (*value == -1) {
984981
Py_RETURN_NONE;
985982
}
986983
return PyLong_FromLong(*value);

0 commit comments

Comments
 (0)