What is ast.NodeVisitor in Python?

Python ast module

The ASTAbstract Syntax Tree - tree representation of source code module allows us to interact with Python code and modify it.

Python comes with abstract syntax grammar, which is subject to change with every Python release. This module helps applications process trees of syntax and find out programmatically what the current syntax grammar looks like.

Abstract syntax trees are great tools for program analysis and program transformation systems.

What is the ast.NodeVisitor method?

ast.NodeVisitor is a base class defined in the ast module that allows us to visit the nodes in an Abstract Syntax Tree. It calls a visitor function at every node, which returns a value that is forwarded by the visit() method.

The visit() method

visit() visits the node and calls the method self.visit_classname, where classname is the name of the node class. If the self.visit_classname method does not exist, generic_visit() is called.

The generic_visit() method

generic_visit() calls the visit() method on all the children of the respective node.


The children nodes of nodes that have a custom visitor method will not be called unless generic_visit is explicitly called on them.


This class is meant to be inherited by subclasses that will add their visitor methods.

Code

The following Python code illustrates an example of how we use the NodeVisitor class:

import ast
from pprint import pprint
class AwaitVisitor(ast.NodeVisitor):
def visit_Await(self, node):
print('Node type: Await\nFields: ', node._fields)
self.generic_visit(node)
def visit_Call(self,node):
print('Node type: Call\nFields: ', node._fields)
ast.NodeVisitor.generic_visit(self, node)
def visit_Name(self,node):
print('Node type: Name\nFields: ', node._fields)
ast.NodeVisitor.generic_visit(self, node)
visitor = AwaitVisitor()
tree = ast.parse("""
async def someFunc():
await other_func()
""")
pprint(ast.dump(tree))
visitor.visit(tree)

Explanation

In this example, we use the parse() function to parse a piece of code that contains the definition of an asynchronous function. This function waits for another function’s execution in the await statement.

  • We define an AwaitVisitor class that extends from the parent class ast.NodeVisitor. This is the subclass that we create in line 4.

  • We override the predefined visit_Await, visit_Call, and visit_Name methods in the parent class, which receive the Await, Call, and Name nodes, respectively.

  • In these methods, we print the type and the fields inside the node and call the generic_visit() method to visit the children nodes of the input node.

  • We initialize a visitor object of the class AwaitVisitor in line 18.

  • We write a definition of a Python asynchronous function and send it to the ast.parse() method, which returns the result of the expression after evaluation, and then stores this result in tree.

  • The ast.dump() method returns a formatted string of the tree structure in tree. You can observe the string returned by the dump function in the output of the code.

  • Then we call the inbuilt visit method available to the visitor object, which visits all the nodes in the tree structure.

    You can observe how the visitor visits each node in the AST in the code output.