New submission from Kai Xia <[email protected]>:

I was trying to construct an ast object dynamically and I think I can identify 
some potential issue.

With the following snippet:

```
#!/usr/bin/env python3
import ast
import sys

print(sys.version)

good = ast.Assign(
    targets=[ast.Name(id="hello", ctx=ast.Store())],
    value=ast.Constant(value="world"),
    lineno=1
)
print(ast.unparse(good))


bad = ast.Assign(
    targets=[ast.Name(id="hello", ctx=ast.Store())],
    value=ast.Constant(value="world"),
)
print(ast.unparse(bad))
```

On my box the output looks like:

```
3.9.6 (default, Jun 29 2021, 05:25:02)
[Clang 12.0.5 (clang-1205.0.22.9)]
hello = 'world'
Traceback (most recent call last):
  File "/Users/xiaket/py.py", line 19, in <module>
    print(ast.unparse(bad))
  File 
"/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ast.py",
 line 1572, in unparse
    return unparser.visit(ast_obj)
  File 
"/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ast.py",
 line 801, in visit
    self.traverse(node)
  File 
"/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ast.py",
 line 795, in traverse
    super().visit(node)
  File 
"/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ast.py",
 line 407, in visit
    return visitor(node)
  File 
"/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ast.py",
 line 858, in visit_Assign
    if type_comment := self.get_type_comment(node):
  File 
"/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ast.py",
 line 786, in get_type_comment
    comment = self._type_ignores.get(node.lineno) or node.type_comment
AttributeError: 'Assign' object has no attribute 'lineno'
```

As I can understand, when we need to construct the Assign object, we'll need to 
provide two keyword arguments, targets and value. We don't need to provide the 
`lineno` as it should be an attribute of the statement node. Also, if we don't 
run `unparse` against the object, apparently it works fine.

I think in the `get_type_comment` method, we are making the assumption that the 
lineno is set automatically, this is true when we are parsing python source 
code as string. But when we are creating the object from scratch, we don't have 
that `lineno` attribute and it will fail.

----------
components: Library (Lib)
messages: 399427
nosy: xiaket
priority: normal
severity: normal
status: open
title: Issue with unparse in ast module
type: behavior
versions: Python 3.9

_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue44896>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to