Skip to content

Commit bc5233b

Browse files
sobolevnvstinner
andauthored
gh-130775: Allow negative locations in ast (#130795)
Co-authored-by: Victor Stinner <[email protected]>
1 parent 8e260b3 commit bc5233b

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

Diff for: Lib/test/test_ast/test_ast.py

+20
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,26 @@ def test_compilation_of_ast_nodes_with_default_end_position_values(self):
189189
# Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode.
190190
compile(tree, "<string>", "exec")
191191

192+
def test_negative_locations_for_compile(self):
193+
# See https://github.com/python/cpython/issues/130775
194+
alias = ast.alias(name='traceback', lineno=0, col_offset=0)
195+
for attrs in (
196+
{'lineno': -2, 'col_offset': 0},
197+
{'lineno': 0, 'col_offset': -2},
198+
{'lineno': 0, 'col_offset': -2, 'end_col_offset': -2},
199+
{'lineno': -2, 'end_lineno': -2, 'col_offset': 0},
200+
):
201+
with self.subTest(attrs=attrs):
202+
tree = ast.Module(body=[
203+
ast.Import(names=[alias], **attrs)
204+
], type_ignores=[])
205+
206+
# It used to crash on this step:
207+
compile(tree, "<string>", "exec")
208+
209+
# This also must not crash:
210+
ast.parse(tree, optimize=2)
211+
192212
def test_slice(self):
193213
slc = ast.parse("x[::]").body[0].value.slice
194214
self.assertIsNone(slc.upper)
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.

Diff for: Python/assemble.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -290,18 +290,15 @@ write_location_info_entry(struct assembler* a, location loc, int isize)
290290
assert(len > THEORETICAL_MAX_ENTRY_SIZE);
291291
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
292292
}
293-
if (loc.lineno < 0) {
294-
assert(loc.lineno == NO_LOCATION.lineno);
293+
if (loc.lineno == NO_LOCATION.lineno) {
295294
write_location_info_none(a, isize);
296295
return SUCCESS;
297296
}
298297
int line_delta = loc.lineno - a->a_lineno;
299298
int column = loc.col_offset;
300299
int end_column = loc.end_col_offset;
301-
assert(column >= -1);
302-
assert(end_column >= -1);
303300
if (column < 0 || end_column < 0) {
304-
if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
301+
if (loc.end_lineno == loc.lineno || loc.end_lineno < 0) {
305302
write_location_info_no_column(a, isize, line_delta);
306303
a->a_lineno = loc.lineno;
307304
return SUCCESS;

0 commit comments

Comments
 (0)