9

I'm playing with python ast (abstract syntax tree).

I wrote the following and it visited all nodes of the AST.

import ast

class Py2Neko(ast.NodeVisitor):
    def generic_visit(self, node):
              print type(node).__name__
              ast.NodeVisitor.generic_visit(self, node)

       def visit_Name(self, node):
              print 'Name :', node.id

       def visit_Num(self, node):
              print 'Num :', node.__dict__['n']

       def visit_Str(self, node):
              print "Str :", node.s

if __name__ == '__main__':

    node = ast.parse("a = 1 + 2")

    print ast.dump(node)

    v = Py2Neko()
    v.visit(node)

Then added some methods to Py2Neko class

def visit_Print(self, node):
    print "Print :"

def visit_Assign(self, node):
    print "Assign :"

def visit_Expr(self, node):
    print "Expr :"

But then when it encounters a "print" statement or an assignement or an expression it seems that it stops and isn't going further.

It outputs:

Module(body=[Assign(targets=[Name(id='a', ctx=Store())], value=BinOp(left=Num(n=1), op=Add(),       right=Num(n=2)))])
Module
Assign :

Can someone tell me what I did wrong.

I'm using Python 2.6.6

2 Answers 2

11

Since your visit_Assign method does not explicitly process the child nodes of the Assign node, traversal of the syntax tree stops there.

If you have a look at the NodeVisitor.generic_visit method in the implementation of ast.py, you'll see that it loops through the children of the current node. So, you can explicitly call the base class generic_visit method from each of your methods that needs to process children:

import ast

class Py2Neko(ast.NodeVisitor):
    def generic_visit(self, node):
        print type(node).__name__
        ast.NodeVisitor.generic_visit(self, node)

    def visit_Name(self, node):
        print 'Name :', node.id

    def visit_Num(self, node):
        print 'Num :', node.__dict__['n']

    def visit_Str(self, node):
        print "Str :", node.s

    def visit_Print(self, node):
        print "Print :"
        ast.NodeVisitor.generic_visit(self, node)

    def visit_Assign(self, node):
        print "Assign :"
        ast.NodeVisitor.generic_visit(self, node)

    def visit_Expr(self, node):
        print "Expr :"
        ast.NodeVisitor.generic_visit(self, node)

if __name__ == '__main__':
    node = ast.parse("a = 1 + 2")

    print ast.dump(node)

    v = Py2Neko()
    v.visit(node)
Sign up to request clarification or add additional context in comments.

1 Comment

ok, I got what you explained, it's clear now, thank you very much!
4

For non-terminal nodes, your visit function has to visit the children. See Simple example of how to use ast.NodeVisitor? for some more information.

2 Comments

D'oh - I was thinking of this but somehow (irrationally) assumed the NodeVisitor would handle this on it's own.
I saw the example you provide but how to specify to visit the children? For example here: dev.pocoo.org/hg/sandbox/file/98ce1ce17c7c/ast/codegen.py they have visit_Print() and others and it seems to work but not for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.