From 4e62ac5fa9f69e759328df1f5ab12a835016a61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 1 Jun 2022 00:51:10 +0200 Subject: [PATCH] Ensure that AST nodes without explicit end positions can be compiled --- ...plicit-end-positions-can-be-compiled.patch | 186 ++++++++++++++++++ python3.11.spec | 4 + 2 files changed, 190 insertions(+) create mode 100644 00381-gh-92597-ensure-that-ast-nodes-without-explicit-end-positions-can-be-compiled.patch diff --git a/00381-gh-92597-ensure-that-ast-nodes-without-explicit-end-positions-can-be-compiled.patch b/00381-gh-92597-ensure-that-ast-nodes-without-explicit-end-positions-can-be-compiled.patch new file mode 100644 index 0000000..7c5a259 --- /dev/null +++ b/00381-gh-92597-ensure-that-ast-nodes-without-explicit-end-positions-can-be-compiled.patch @@ -0,0 +1,186 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Pablo Galindo Salgado +Date: Wed, 1 Jun 2022 00:00:47 +0100 +Subject: [PATCH] 00381: gh-92597: Ensure that AST nodes without explicit end + positions can be compiled + +(cherry picked from commit 705eaec28f7bee530b1c1635ba385a49a1feaf32) +--- + Lib/test/test_ast.py | 8 +++++++ + ...2-05-30-19-00-38.gh-issue-93359.zXV3A0.rst | 2 ++ + Parser/asdl_c.py | 14 ++++++++++- + Python/Python-ast.c | 24 +++++++++---------- + 4 files changed, 35 insertions(+), 13 deletions(-) + create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-30-19-00-38.gh-issue-93359.zXV3A0.rst + +diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py +index 896eb5bedd..33df22cb35 100644 +--- a/Lib/test/test_ast.py ++++ b/Lib/test/test_ast.py +@@ -362,6 +362,14 @@ def test_invalid_position_information(self): + with self.assertRaises(ValueError): + compile(tree, '', 'exec') + ++ def test_compilation_of_ast_nodes_with_default_end_position_values(self): ++ tree = ast.Module(body=[ ++ ast.Import(names=[ast.alias(name='builtins', lineno=1, col_offset=0)], lineno=1, col_offset=0), ++ ast.Import(names=[ast.alias(name='traceback', lineno=0, col_offset=0)], lineno=0, col_offset=1) ++ ], type_ignores=[]) ++ ++ # Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode. ++ compile(tree, "", "exec") + + def test_slice(self): + slc = ast.parse("x[::]").body[0].value.slice +diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-30-19-00-38.gh-issue-93359.zXV3A0.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-30-19-00-38.gh-issue-93359.zXV3A0.rst +new file mode 100644 +index 0000000000..36e5e52390 +--- /dev/null ++++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-30-19-00-38.gh-issue-93359.zXV3A0.rst +@@ -0,0 +1,2 @@ ++Ensure that custom :mod:`ast` nodes without explicit end positions can be ++compiled. Patch by Pablo Galindo. +diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py +index 3bfe320fe3..1101a3593d 100755 +--- a/Parser/asdl_c.py ++++ b/Parser/asdl_c.py +@@ -488,6 +488,12 @@ def visitProduct(self, prod, name): + + + class Obj2ModVisitor(PickleVisitor): ++ ++ attribute_special_defaults = { ++ "end_lineno": "lineno", ++ "end_col_offset": "col_offset", ++ } ++ + @contextmanager + def recursive_call(self, node, level): + self.emit('if (_Py_EnterRecursiveCall(" while traversing \'%s\' node")) {' % node, level, reflow=False) +@@ -637,7 +643,13 @@ def visitField(self, field, name, sum=None, prod=None, depth=0): + self.emit("if (tmp == NULL || tmp == Py_None) {", depth) + self.emit("Py_CLEAR(tmp);", depth+1) + if self.isNumeric(field): +- self.emit("%s = 0;" % field.name, depth+1) ++ if field.name in self.attribute_special_defaults: ++ self.emit( ++ "%s = %s;" % (field.name, self.attribute_special_defaults[field.name]), ++ depth+1, ++ ) ++ else: ++ self.emit("%s = 0;" % field.name, depth+1) + elif not self.isSimpleType(field): + self.emit("%s = NULL;" % field.name, depth+1) + else: +diff --git a/Python/Python-ast.c b/Python/Python-ast.c +index 3861eaf978..e52a72d43b 100644 +--- a/Python/Python-ast.c ++++ b/Python/Python-ast.c +@@ -5697,7 +5697,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_lineno = 0; ++ end_lineno = lineno; + } + else { + int res; +@@ -5714,7 +5714,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_col_offset = 0; ++ end_col_offset = col_offset; + } + else { + int res; +@@ -8114,7 +8114,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_lineno = 0; ++ end_lineno = lineno; + } + else { + int res; +@@ -8131,7 +8131,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_col_offset = 0; ++ end_col_offset = col_offset; + } + else { + int res; +@@ -10291,7 +10291,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_lineno = 0; ++ end_lineno = lineno; + } + else { + int res; +@@ -10308,7 +10308,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_col_offset = 0; ++ end_col_offset = col_offset; + } + else { + int res; +@@ -10755,7 +10755,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_lineno = 0; ++ end_lineno = lineno; + } + else { + int res; +@@ -10772,7 +10772,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_col_offset = 0; ++ end_col_offset = col_offset; + } + else { + int res; +@@ -10877,7 +10877,7 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_lineno = 0; ++ end_lineno = lineno; + } + else { + int res; +@@ -10894,7 +10894,7 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_col_offset = 0; ++ end_col_offset = col_offset; + } + else { + int res; +@@ -10999,7 +10999,7 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_lineno = 0; ++ end_lineno = lineno; + } + else { + int res; +@@ -11016,7 +11016,7 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); +- end_col_offset = 0; ++ end_col_offset = col_offset; + } + else { + int res; diff --git a/python3.11.spec b/python3.11.spec index 111050f..b1d1c51 100644 --- a/python3.11.spec +++ b/python3.11.spec @@ -310,6 +310,10 @@ Patch251: 00251-change-user-install-location.patch # Ideally, we should talk to upstream and explain why we don't want this Patch328: 00328-pyc-timestamp-invalidation-mode.patch +# 00381 # d7e0c24c40417744f227744f9d6875670b7c187e +# gh-92597: Ensure that AST nodes without explicit end positions can be compiled +Patch381: 00381-gh-92597-ensure-that-ast-nodes-without-explicit-end-positions-can-be-compiled.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc.,