bpo-43950: use 0-indexed column offsets for bytecode positions (GH-27011)

This commit is contained in:
Batuhan Taskaya 2021-07-04 21:02:16 +03:00 committed by GitHub
parent d33943a6c3
commit 44f91fc802
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 22 deletions

View file

@ -344,7 +344,7 @@ class CodeTest(unittest.TestCase):
# get assigned the first_lineno but they don't have other positions. # get assigned the first_lineno but they don't have other positions.
# There is no easy way of inferring them at that stage, so for now # There is no easy way of inferring them at that stage, so for now
# we don't support it. # we don't support it.
self.assertTrue(all(positions) or not any(positions)) self.assertTrue(positions.count(None) in [0, 4])
if not any(positions): if not any(positions):
artificial_instructions.append(instr) artificial_instructions.append(instr)

View file

@ -1006,8 +1006,8 @@ class TestSourcePositions(unittest.TestCase):
return return
lines.add(node.lineno) lines.add(node.lineno)
end_lines.add(node.end_lineno) end_lines.add(node.end_lineno)
columns.add(node.col_offset + 1) columns.add(node.col_offset)
end_columns.add(node.end_col_offset + 1) end_columns.add(node.end_col_offset)
SourceOffsetVisitor().visit(ast_tree) SourceOffsetVisitor().visit(ast_tree)
@ -1058,10 +1058,10 @@ class TestSourcePositions(unittest.TestCase):
self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_SUBTRACT', self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_SUBTRACT',
line=10_000 + 2, end_line=10_000 + 2, line=10_000 + 2, end_line=10_000 + 2,
column=3, end_column=9) column=2, end_column=8)
self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_ADD', self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_ADD',
line=10_000 + 4, end_line=10_000 + 4, line=10_000 + 4, end_line=10_000 + 4,
column=3, end_column=10) column=2, end_column=9)
def test_multiline_expression(self): def test_multiline_expression(self):
snippet = """\ snippet = """\
@ -1071,7 +1071,7 @@ f(
""" """
compiled_code, _ = self.check_positions_against_ast(snippet) compiled_code, _ = self.check_positions_against_ast(snippet)
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL_FUNCTION', self.assertOpcodeSourcePositionIs(compiled_code, 'CALL_FUNCTION',
line=1, end_line=3, column=1, end_column=2) line=1, end_line=3, column=0, end_column=1)
def test_very_long_line_end_offset(self): def test_very_long_line_end_offset(self):
# Make sure we get None for when the column offset is too large to # Make sure we get None for when the column offset is too large to
@ -1088,15 +1088,15 @@ f(
compiled_code, _ = self.check_positions_against_ast(snippet) compiled_code, _ = self.check_positions_against_ast(snippet)
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_SUBSCR', self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_SUBSCR',
line=1, end_line=1, column=14, end_column=22) line=1, end_line=1, column=13, end_column=21)
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_MULTIPLY', self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_MULTIPLY',
line=1, end_line=1, column=10, end_column=22) line=1, end_line=1, column=9, end_column=21)
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_ADD', self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_ADD',
line=1, end_line=1, column=10, end_column=27) line=1, end_line=1, column=9, end_column=26)
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_MATRIX_MULTIPLY', self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_MATRIX_MULTIPLY',
line=1, end_line=1, column=5, end_column=28) line=1, end_line=1, column=4, end_column=27)
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_SUBTRACT', self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_SUBTRACT',
line=1, end_line=1, column=1, end_column=28) line=1, end_line=1, column=0, end_column=27)
class TestExpressionStackSize(unittest.TestCase): class TestExpressionStackSize(unittest.TestCase):

View file

@ -610,9 +610,6 @@ PyCode_Addr2Location(PyCodeObject *co, int addrq,
int *end_line, int *end_column) int *end_line, int *end_column)
{ {
*start_line = PyCode_Addr2Line(co, addrq); *start_line = PyCode_Addr2Line(co, addrq);
if (*start_line == -1) {
*start_line = 0;
}
*start_column = _PyCode_Addr2Offset(co, addrq); *start_column = _PyCode_Addr2Offset(co, addrq);
*end_line = _PyCode_Addr2EndLine(co, addrq); *end_line = _PyCode_Addr2EndLine(co, addrq);
*end_column = _PyCode_Addr2EndOffset(co, addrq); *end_column = _PyCode_Addr2EndOffset(co, addrq);
@ -626,7 +623,7 @@ _PyCode_Addr2EndLine(PyCodeObject* co, int addrq)
return co->co_firstlineno; return co->co_firstlineno;
} }
else if (co->co_endlinetable == Py_None) { else if (co->co_endlinetable == Py_None) {
return 0; return -1;
} }
assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code)); assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code));
@ -639,34 +636,34 @@ int
_PyCode_Addr2Offset(PyCodeObject* co, int addrq) _PyCode_Addr2Offset(PyCodeObject* co, int addrq)
{ {
if (co->co_columntable == Py_None || addrq < 0) { if (co->co_columntable == Py_None || addrq < 0) {
return 0; return -1;
} }
if (addrq % 2 == 1) { if (addrq % 2 == 1) {
--addrq; --addrq;
} }
if (addrq >= PyBytes_GET_SIZE(co->co_columntable)) { if (addrq >= PyBytes_GET_SIZE(co->co_columntable)) {
return 0; return -1;
} }
unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable); unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable);
return bytes[addrq]; return bytes[addrq] - 1;
} }
int int
_PyCode_Addr2EndOffset(PyCodeObject* co, int addrq) _PyCode_Addr2EndOffset(PyCodeObject* co, int addrq)
{ {
if (co->co_columntable == Py_None || addrq < 0) { if (co->co_columntable == Py_None || addrq < 0) {
return 0; return -1;
} }
if (addrq % 2 == 0) { if (addrq % 2 == 0) {
++addrq; ++addrq;
} }
if (addrq >= PyBytes_GET_SIZE(co->co_columntable)) { if (addrq >= PyBytes_GET_SIZE(co->co_columntable)) {
return 0; return -1;
} }
unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable); unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable);
return bytes[addrq]; return bytes[addrq] - 1;
} }
void void
@ -980,7 +977,7 @@ positionsiter_dealloc(positionsiterator* pi)
static PyObject* static PyObject*
_source_offset_converter(int* value) { _source_offset_converter(int* value) {
if (*value <= 0) { if (*value == -1) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
return PyLong_FromLong(*value); return PyLong_FromLong(*value);