From 44f91fc802a2b71312e9abd9e8e9dcbf02e8216d Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Sun, 4 Jul 2021 21:02:16 +0300 Subject: bpo-43950: use 0-indexed column offsets for bytecode positions (GH-27011) --- Lib/test/test_code.py | 2 +- Lib/test/test_compile.py | 20 ++++++++++---------- Objects/codeobject.c | 19 ++++++++----------- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 55ba30a..24d27c0 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -344,7 +344,7 @@ class CodeTest(unittest.TestCase): # 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 # 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): artificial_instructions.append(instr) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 47deda0..bc8c57d 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1006,8 +1006,8 @@ class TestSourcePositions(unittest.TestCase): return lines.add(node.lineno) end_lines.add(node.end_lineno) - columns.add(node.col_offset + 1) - end_columns.add(node.end_col_offset + 1) + columns.add(node.col_offset) + end_columns.add(node.end_col_offset) SourceOffsetVisitor().visit(ast_tree) @@ -1058,10 +1058,10 @@ class TestSourcePositions(unittest.TestCase): self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_SUBTRACT', 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', line=10_000 + 4, end_line=10_000 + 4, - column=3, end_column=10) + column=2, end_column=9) def test_multiline_expression(self): snippet = """\ @@ -1071,7 +1071,7 @@ f( """ compiled_code, _ = self.check_positions_against_ast(snippet) 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): # 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) 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', - 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', - 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', - 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', - line=1, end_line=1, column=1, end_column=28) + line=1, end_line=1, column=0, end_column=27) class TestExpressionStackSize(unittest.TestCase): diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 6789588..aa36175 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -610,9 +610,6 @@ PyCode_Addr2Location(PyCodeObject *co, int addrq, int *end_line, int *end_column) { *start_line = PyCode_Addr2Line(co, addrq); - if (*start_line == -1) { - *start_line = 0; - } *start_column = _PyCode_Addr2Offset(co, addrq); *end_line = _PyCode_Addr2EndLine(co, addrq); *end_column = _PyCode_Addr2EndOffset(co, addrq); @@ -626,7 +623,7 @@ _PyCode_Addr2EndLine(PyCodeObject* co, int addrq) return co->co_firstlineno; } else if (co->co_endlinetable == Py_None) { - return 0; + return -1; } assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code)); @@ -639,34 +636,34 @@ int _PyCode_Addr2Offset(PyCodeObject* co, int addrq) { if (co->co_columntable == Py_None || addrq < 0) { - return 0; + return -1; } if (addrq % 2 == 1) { --addrq; } if (addrq >= PyBytes_GET_SIZE(co->co_columntable)) { - return 0; + return -1; } unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable); - return bytes[addrq]; + return bytes[addrq] - 1; } int _PyCode_Addr2EndOffset(PyCodeObject* co, int addrq) { if (co->co_columntable == Py_None || addrq < 0) { - return 0; + return -1; } if (addrq % 2 == 0) { ++addrq; } if (addrq >= PyBytes_GET_SIZE(co->co_columntable)) { - return 0; + return -1; } unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable); - return bytes[addrq]; + return bytes[addrq] - 1; } void @@ -980,7 +977,7 @@ positionsiter_dealloc(positionsiterator* pi) static PyObject* _source_offset_converter(int* value) { - if (*value <= 0) { + if (*value == -1) { Py_RETURN_NONE; } return PyLong_FromLong(*value); -- cgit v0.12