You can use ast to properly parse all the module:
import inspect
import importlib
import ast
class ParseMod(ast.NodeVisitor):
def visit_FuncDef(self,node):
print("In func")
print(node.name)
print(node.args)
self.generic_visit(node)
def visit_ClassDef(self,node):
print("in class")
print(node.name)
for n in node.body:
print(n.name)
self.generic_visit(node)
def visit_Call(self, node):
print("In call")
print(node.func.id)
print([ast.literal_eval(arg) for arg in node.args])
self.generic_visit(node)
mod = "test2"
mod = importlib.import_module(mod)
p = ast.parse(inspect.getsource(mod))
par = ParseMod()
par.visit(p)
Input:
class Foobar(object):
def func(self):
return "func"
class Bar(object):
def func2(self):
return "func2"
class Foo():
def __init__(self):
self.x = 1
self.y = 2
self.z = 3
def func_foo(self):
return "func_foo"
def some_func(a,b):
"""
:param a: int
:param b: int
:return: int
"""
return a,b
some_func(1,2)
Output:
in class
Foobar
func
in class
Bar
func2
in class
Foo
__init__
func_foo
In call
some_func
[1, 2]
There is a full list of all the available attributes and an explanation of each in the greentreesnakes docs.
If you just want to collect the function and class nodes:
import inspect
import importlib
import ast
mod = "test"
mod = importlib.import_module(mod)
p = ast.parse(inspect.getsource(mod))
classes = [node for node in p.body if isinstance(node, ast.ClassDef)]
funcs = [node for node in p.body if isinstance(node, ast.FunctionDef)]
print(classes)
print(funcs)
[<_ast.ClassDef object at 0x7f9bc7884190>, <_ast.ClassDef object at 0x7f9bc7884350>, <_ast.ClassDef object at 0x7f9bc7884510>]
[<_ast.FunctionDef object at 0x7f89d3377c50>]
Then extract what you want from each:
for f in funcs:
print(f.name)
print([a.id for a in f.args.args])
print(ast.get_docstring(f))
some_func
['a', 'b']
:param a: int
:param b: int
:return: int
There are a couple more example usages here and here