https://github.com/python/cpython/commit/7a8364460d9f14a88cf6b21058461f8c30777c9e
commit: 7a8364460d9f14a88cf6b21058461f8c30777c9e
branch: 3.13
author: sobolevn <m...@sobolevn.me>
committer: Yhg1s <tho...@python.org>
date: 2025-04-08T10:47:24+02:00
summary:

[3.13] gh-130775: Allow negative locations in `ast` (GH-130795) (#132243)

(cherry picked from commit bc5233b6a5cdd8f77a4737ce317f94110869c082)

Co-authored-by: Victor Stinner <vstin...@python.org>

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst
M Lib/test/test_ast/test_ast.py
M Python/assemble.c

diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py
index 0bb74582f3ecdf..7ac5a816bf0229 100644
--- a/Lib/test/test_ast/test_ast.py
+++ b/Lib/test/test_ast/test_ast.py
@@ -204,6 +204,26 @@ def 
test_compilation_of_ast_nodes_with_default_end_position_values(self):
         # Check that compilation doesn't crash. Note: this may crash 
explicitly only on debug mode.
         compile(tree, "<string>", "exec")
 
+    def test_negative_locations_for_compile(self):
+        # See https://github.com/python/cpython/issues/130775
+        alias = ast.alias(name='traceback', lineno=0, col_offset=0)
+        for attrs in (
+            {'lineno': -2, 'col_offset': 0},
+            {'lineno': 0, 'col_offset': -2},
+            {'lineno': 0, 'col_offset': -2, 'end_col_offset': -2},
+            {'lineno': -2, 'end_lineno': -2, 'col_offset': 0},
+        ):
+            with self.subTest(attrs=attrs):
+                tree = ast.Module(body=[
+                    ast.Import(names=[alias], **attrs)
+                ], type_ignores=[])
+
+                # It used to crash on this step:
+                compile(tree, "<string>", "exec")
+
+                # This also must not crash:
+                ast.parse(tree, optimize=2)
+
     def test_slice(self):
         slc = ast.parse("x[::]").body[0].value.slice
         self.assertIsNone(slc.upper)
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst
new file mode 100644
index 00000000000000..53408cd427596c
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-20-02-45.gh-issue-130775.fEM6T-.rst
@@ -0,0 +1 @@
+Do not crash on negative ``column`` and ``end_column`` in :mod:`ast` locations.
diff --git a/Python/assemble.c b/Python/assemble.c
index 98816aec783227..35453277dd84d1 100644
--- a/Python/assemble.c
+++ b/Python/assemble.c
@@ -290,17 +290,15 @@ write_location_info_entry(struct assembler* a, location 
loc, int isize)
         assert(len > THEORETICAL_MAX_ENTRY_SIZE);
         RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
     }
-    if (loc.lineno < 0) {
+    if (loc.lineno == NO_LOCATION.lineno) {
         write_location_info_none(a, isize);
         return SUCCESS;
     }
     int line_delta = loc.lineno - a->a_lineno;
     int column = loc.col_offset;
     int end_column = loc.end_col_offset;
-    assert(column >= -1);
-    assert(end_column >= -1);
     if (column < 0 || end_column < 0) {
-        if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
+        if (loc.end_lineno == loc.lineno || loc.end_lineno < 0) {
             write_location_info_no_column(a, isize, line_delta);
             a->a_lineno = loc.lineno;
             return SUCCESS;

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to