berkerpeksag / astor

Python AST read/write
https://pypi.org/project/astor/
BSD 3-Clause "New" or "Revised" License
810 stars 102 forks source link

Python 3.5 - AttributeError: 'Expr' object has no attribute 'value' #49

Closed aron-bordin closed 8 years ago

aron-bordin commented 8 years ago

Hi!

I have the following example:

import astor
import ast

class CallWrapper(ast.NodeTransformer):
    def visit_Call(self, node):
        if node.col_offset == 0:
            return None
        return node

src = open('test.py', 'r').read()
p = ast.parse(src)
CallWrapper().visit(p)
ast.fix_missing_locations(p)
new_src = astor.to_source(p)

print(new_src)

It works with Python 2.7, but raise the following error on Python3.5

Traceback (most recent call last):
  File "easy.py", line 15, in <module>
    new_src = astor.to_source(p)
  File "/usr/lib/python3.5/site-packages/astor-0.6-py3.5.egg/astor/code_gen.py", line 51, in to_source
    generator.visit(node)
  File "/usr/lib/python3.5/site-packages/astor-0.6-py3.5.egg/astor/node_util.py", line 137, in visit
    return visitor(node)
  File "/usr/lib/python3.5/site-packages/astor-0.6-py3.5.egg/astor/code_gen.py", line 662, in visit_Module
    self.write(*node.body)
  File "/usr/lib/python3.5/site-packages/astor-0.6-py3.5.egg/astor/code_gen.py", line 156, in write
    self.visit(item)
  File "/usr/lib/python3.5/site-packages/astor-0.6-py3.5.egg/astor/node_util.py", line 137, in visit
    return visitor(node)
  File "/usr/lib/python3.5/site-packages/astor-0.6-py3.5.egg/astor/code_gen.py", line 260, in visit_Expr
    set_precedence(node, node.value)
AttributeError: 'Expr' object has no attribute 'value'

Am I missing something? Is it a bug? If so, please if possible, point me some direction that I'd love to create a PR.

Thank you

aron-bordin commented 8 years ago

I tested using only ast, and I see that it works with def visit_Expr instead of def visit_Call. So the problem is on my transformer, sorry :confused:

But using only ast, this transformer was not working on python2 and not working on py3; with astor, it works on py2. I'm closing the issue, because it seems to be a problem with my transformer(this is my first usage of ast), but if there is anything that I can help, I'd love to help ;)

Thx

pmaupin commented 8 years ago

Without thinking too hard about your code and what is going on, you could certainly replace the statement:

def visit_Expr(self, node):
    set_precedence(node, node.value)
    ...

With:

def visit_Expr(self, node):
    if hasattr(node, 'value'):
        set_precedence(node, node.value)
    ...

to see if that helps. But if you want to open a PR, you'd need to explain carefully what this is good for, with a good example (and preferably a test case).

Regards, Pat

shanjng commented 2 years ago

I received the same error when using visit_Call() then doing astor.to_source(). The issue can be fixed with 'return ast.Expr(value=None)' instead of 'return None'