Author serhiy.storchaka
Recipients serhiy.storchaka
Date 2019-08-26.07:35:54
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1566804954.58.0.654310469231.issue37950@roundup.psfhosted.org>
In-reply-to
Content
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)'
History
Date User Action Args
2019-08-26 07:35:54serhiy.storchakasetrecipients: + serhiy.storchaka
2019-08-26 07:35:54serhiy.storchakasetmessageid: <1566804954.58.0.654310469231.issue37950@roundup.psfhosted.org>
2019-08-26 07:35:54serhiy.storchakalinkissue37950 messages
2019-08-26 07:35:54serhiy.storchakacreate