Ensure that AST nodes without explicit end positions can be compiled
This commit is contained in:
		
							parent
							
								
									f8d78fe8c7
								
							
						
					
					
						commit
						4e62ac5fa9
					
				| @ -0,0 +1,186 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Pablo Galindo Salgado <Pablogsal@gmail.com> | ||||||
|  | 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, '<string>', '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, "<string>", "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; | ||||||
| @ -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 | # Ideally, we should talk to upstream and explain why we don't want this | ||||||
| Patch328: 00328-pyc-timestamp-invalidation-mode.patch | 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 ^^^) | # (New patches go here ^^^) | ||||||
| # | # | ||||||
| # When adding new patches to "python" and "python3" in Fedora, EL, etc., | # When adding new patches to "python" and "python3" in Fedora, EL, etc., | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user