Skip to content

Commit 705eaec

Browse files
authored
gh-92597: Ensure that AST nodes without explicit end positions can be compiled (GH-93359)
1 parent fc69436 commit 705eaec

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

Lib/test/test_ast.py

+8
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,14 @@ def test_invalid_position_information(self):
362362
with self.assertRaises(ValueError):
363363
compile(tree, '<string>', 'exec')
364364

365+
def test_compilation_of_ast_nodes_with_default_end_position_values(self):
366+
tree = ast.Module(body=[
367+
ast.Import(names=[ast.alias(name='builtins', lineno=1, col_offset=0)], lineno=1, col_offset=0),
368+
ast.Import(names=[ast.alias(name='traceback', lineno=0, col_offset=0)], lineno=0, col_offset=1)
369+
], type_ignores=[])
370+
371+
# Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode.
372+
compile(tree, "<string>", "exec")
365373

366374
def test_slice(self):
367375
slc = ast.parse("x[::]").body[0].value.slice
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Ensure that custom :mod:`ast` nodes without explicit end positions can be
2+
compiled. Patch by Pablo Galindo.

Parser/asdl_c.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,12 @@ def visitProduct(self, prod, name):
488488

489489

490490
class Obj2ModVisitor(PickleVisitor):
491+
492+
attribute_special_defaults = {
493+
"end_lineno": "lineno",
494+
"end_col_offset": "col_offset",
495+
}
496+
491497
@contextmanager
492498
def recursive_call(self, node, level):
493499
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):
637643
self.emit("if (tmp == NULL || tmp == Py_None) {", depth)
638644
self.emit("Py_CLEAR(tmp);", depth+1)
639645
if self.isNumeric(field):
640-
self.emit("%s = 0;" % field.name, depth+1)
646+
if field.name in self.attribute_special_defaults:
647+
self.emit(
648+
"%s = %s;" % (field.name, self.attribute_special_defaults[field.name]),
649+
depth+1,
650+
)
651+
else:
652+
self.emit("%s = 0;" % field.name, depth+1)
641653
elif not self.isSimpleType(field):
642654
self.emit("%s = NULL;" % field.name, depth+1)
643655
else:

Python/Python-ast.c

+12-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)