In [2]:
import ast
import os
In [3]:
def setuppy_to_ast_tree(path_to_setuppy):
with open(path_to_setuppy, 'r') as f:
code = f.read()
print(code)
tree = ast.parse(code)
return tree
In [4]:
setuppy_path = os.path.join(os.path.expanduser('~/dev/python/scikit-xray/setup.py'))
In [5]:
tree = setuppy_to_ast_tree(setuppy_path)
In [6]:
for t in tree.body:
print(t)
In [20]:
for kw in tree.body[-1].value.keywords:
print(vars(kw))
In [115]:
class SetupScraper(ast.NodeVisitor):
def __init__(self):
self.in_setup = False
self.setup_info = []
def visit_keyword(self, node):
if self.in_setup:
self.setup_info.append([node.arg])
print(vars(node))
self.visit(node.value)
def visit_Call(self, node):
if self.in_setup:
self.setup_info[-1].append(node)
if isinstance(node.func, ast.Name) and node.func.id == 'setup':
self.in_setup = True
self.generic_visit(node)
if isinstance(node.func, ast.Name) and node.func.id == 'setup':
self.in_setup = False
def visit_Name(self, node):
if node.id == 'setup':
return
if self.in_setup:
self.setup_info[-1].append(node.id)
print(vars(node))
def visit_Str(self, node):
if self.in_setup:
self.setup_info[-1].append(node.s)
print(node.s)
def generic_visit(self, node):
"""Called if no explicit visitor function exists for a node.
Overridden from the ast.NodeVisitor base class so that I can add some
local state to keep track of whether or not my node visitor is inside
a try/except block. When a try block is encountered, the node is added
to the `trys` instance attribute and then the try block is recursed in
to. Once the recursion has exited, the node is removed from the `trys`
instance attribute
"""
for field, value in ast.iter_fields(node):
if isinstance(value, list):
for item in value:
if isinstance(item, ast.AST):
self.visit(item)
elif isinstance(value, ast.AST):
self.visit(value)
In [116]:
scraper = SetupScraper()
In [117]:
scraper.visit(tree)
In [118]:
scraper.setup_info
Out[118]:
In [111]:
vars(setup_call.value)
In [79]:
for kw in setup_call.value.keywords:
value = kw.value
stringed = ''
# print(value)
if type(value) == ast.Str:
stringed = value.s
elif type(value) == ast.Call:
stringed = value.func.attr + '()'
elif type(value) == ast.List:
stringed = [vars(v) for v in value.elts]
if stringed:
print('%s=%s' % (kw.arg, stringed))
else:
print('%s --> %s --> %s' % (kw.arg, type(value), vars(value)))
In [ ]: