Created
August 10, 2016 13:24
-
-
Save sceeter89/83ddba19ce571ed17b255b8bc010d814 to your computer and use it in GitHub Desktop.
Simple script to analyze AST of expression or entire Python file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sample code to play with analyzer: