From 57ed1d66d6b7ddd52ee2f17d392082e7849d250b Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Sun, 4 Jul 2021 12:00:03 +0300 Subject: [PATCH] bpo-43950: use 0-indexed column offsets for bytecode positions --- 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 55ba30a9f936a0..24d27c0d24046a 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -344,7 +344,7 @@ def test_co_positions_artificial_instructions(self): # 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 47deda09f9010c..bc8c57d9e1d2f4 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1006,8 +1006,8 @@ def generic_visit(self, node): 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 @@ def test_compiles_to_extended_op_arg(self): 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 @@ def test_multiline_expression(self): """ 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 @@ def test_complex_single_line_expression(self): 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 678958891a0bc4..aa36175aa5ad5c 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);