Skip to content

Instantly share code, notes, and snippets.

@sceeter89
Created August 10, 2016 13:24
Show Gist options
  • Save sceeter89/83ddba19ce571ed17b255b8bc010d814 to your computer and use it in GitHub Desktop.
Save sceeter89/83ddba19ce571ed17b255b8bc010d814 to your computer and use it in GitHub Desktop.
Simple script to analyze AST of expression or entire Python file.
import sys
import traceback
import ast
import _ast
import argparse
processed_objects = set()
def print_indented(indentation_size, message):
print(('\t' * indentation_size) + message)
def walk_ast(node, indent=0):
if id(node) in processed_objects:
print_indented(indent, 'Already processed.')
return
processed_objects.add(id(node))
if isinstance(node, list):
if not node:
print_indented(indent, 'Empty list')
return
print_indented(indent, 'Iterating through list elements...')
for n in node:
walk_ast(n, indent+1)
if isinstance(node, _ast.AST) and not isinstance(node, _ast.Load):
print_indented(indent, '* Entering node of type: ' + str(type(node)))
fields = node.__dict__
print_indented(indent, ' Available fields: ' + str(fields))
for field_name in fields:
field = fields[field_name]
if isinstance(field, _ast.AST) or isinstance(field, list):
print_indented(indent, ' Inspecting field: {}...'.format(field_name))
walk_ast(field, indent+1)
child_nodes = list(ast.iter_child_nodes(node))
if not child_nodes:
return
print_indented(indent, ' Iterating node\'s children...')
for child in child_nodes:
walk_ast(child, indent+1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Analyze and display structure of Python code')
parser.add_argument('-f', '--file', help='Path to Python file to parse and analyze.')
parser.add_argument('-e', '--expression', help='Expression to parse and analyze')
args = parser.parse_args()
if args.file:
try:
with open(args.file, mode='r') as f:
root_node = ast.parse(f.read())
walk_ast(root_node)
except Exception as e:
print(e)
traceback.print_exc()
if args.expression:
try:
root_node = compile(args.expression, 'anonymous', mode='eval', flags=ast.PyCF_ONLY_AST)
walk_ast(root_node)
except Exception as e:
print(e)
traceback.print_exc()
@sceeter89
Copy link
Author

Sample code to play with analyzer:

import sys, os
from datetime import date

def function(x, *args, **kwargs):
    if False:
        return x**3
    return x**4

if __name__ == "__main__":
    function(3)

sys.exit(1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment