[New-bugs-announce] [issue37950] ast.dump() with incomplete node

Serhiy Storchaka report at bugs.python.org
Mon Aug 26 03:35:54 EDT 2019


New submission from Serhiy Storchaka <storchaka+cpython at gmail.com>:

There are several issues in ast.dump() with incompletely initialized node. Some fields and attributes of AST nodes are optional, but creating an AST node without them leads ast.dump() to fail or to produce incorrect result.

1. With annotate_fields=False ast.dump() outputs subnodes as positional arguments of the node constructor.

>>> ast.dump(ast.Raise(exc=ast.Name(id='a', ctx=ast.Load()), cause=ast.Name(id='b', ctx=ast.Load())), annotate_fields=False)
"Raise(Name('a', Load()), Name('b', Load()))"

But if miss the optional exc field it outputs incorrect output:

>>> ast.dump(ast.Raise(cause=ast.Name(id='a', ctx=ast.Load())), annotate_fields=False)
"Raise(Name('a', Load()))"

which is not distinguished from the case when you pass only the exc field and miss the cause field (both are optional):

>>> ast.dump(ast.Raise(exc=ast.Name(id='a', ctx=ast.Load())), annotate_fields=False)
"Raise(Name('a', Load()))"

2. The documentation of ast.dump() says that its result with annotate_fields=True is impossible to evaluate, but this is not true, because keyword arguments are supported by AST node constructors.

3. Attributes end_lineno and end_col_offset are optional, but if you miss them ast.dump() with include_attributes=True will fail:

>>> ast.dump(ast.Raise(lineno=3, col_offset=4), include_attributes=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython3.8/Lib/ast.py", line 126, in dump
    return _format(node)
  File "/home/serhiy/py/cpython3.8/Lib/ast.py", line 118, in _format
    rv += ', '.join('%s=%s' % (a, _format(getattr(node, a)))
  File "/home/serhiy/py/cpython3.8/Lib/ast.py", line 118, in <genexpr>
    rv += ', '.join('%s=%s' % (a, _format(getattr(node, a)))
AttributeError: 'Raise' object has no attribute 'end_lineno'

4. Even if you specify all attributes, the output looks weird if you do not specify any field (note a space after "("):

>>> ast.dump(ast.Raise(lineno=3, col_offset=4, end_lineno=3, end_col_offset=24), include_attributes=True)
'Raise( lineno=3, col_offset=4, end_lineno=3, end_col_offset=24)'

----------
assignee: serhiy.storchaka
components: Library (Lib)
messages: 350506
nosy: serhiy.storchaka
priority: normal
severity: normal
status: open
title: ast.dump() with incomplete node
type: behavior
versions: Python 3.7, Python 3.8, Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue37950>
_______________________________________


More information about the New-bugs-announce mailing list