Skip to content

Commit 492a554

Browse files
sobolevnvstinner
andauthored
[3.12] gh-130775: Allow negative locations in ast (GH-130795) (#132260)
(cherry picked from commit bc5233b) Co-authored-by: sobolevn <mail@sobolevn.me> Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent 40f81e1 commit 492a554

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

Lib/test/test_ast/test_ast.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,23 @@ def test_compilation_of_ast_nodes_with_default_end_position_values(self):
160160
# Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode.
161161
compile(tree, "<string>", "exec")
162162

163+
def test_negative_locations_for_compile(self):
164+
# See https://github.com/python/cpython/issues/130775
165+
alias = ast.alias(name='traceback', lineno=0, col_offset=0)
166+
for attrs in (
167+
{'lineno': -2, 'col_offset': 0},
168+
{'lineno': 0, 'col_offset': -2},
169+
{'lineno': 0, 'col_offset': -2, 'end_col_offset': -2},
170+
{'lineno': -2, 'end_lineno': -2, 'col_offset': 0},
171+
):
172+
with self.subTest(attrs=attrs):
173+
tree = ast.Module(body=[
174+
ast.Import(names=[alias], **attrs)
175+
], type_ignores=[])
176+
177+
# It used to crash on this step:
178+
compile(tree, "<string>", "exec")
179+
163180
def test_slice(self):
164181
slc = ast.parse("x[::]").body[0].value.slice
165182
self.assertIsNone(slc.upper)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not crash on negative ``column`` and ``end_column`` in :mod:`ast` locations.

Python/assemble.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,17 +268,15 @@ write_location_info_entry(struct assembler* a, location loc, int isize)
268268
assert(len > THEORETICAL_MAX_ENTRY_SIZE);
269269
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
270270
}
271-
if (loc.lineno < 0) {
271+
if (loc.lineno == NO_LOCATION.lineno) {
272272
write_location_info_none(a, isize);
273273
return SUCCESS;
274274
}
275275
int line_delta = loc.lineno - a->a_lineno;
276276
int column = loc.col_offset;
277277
int end_column = loc.end_col_offset;
278-
assert(column >= -1);
279-
assert(end_column >= -1);
280278
if (column < 0 || end_column < 0) {
281-
if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
279+
if (loc.end_lineno == loc.lineno || loc.end_lineno < 0) {
282280
write_location_info_no_column(a, isize, line_delta);
283281
a->a_lineno = loc.lineno;
284282
return SUCCESS;

0 commit comments

Comments
 (0)