pycallgraph
[perhaps of faint interest to python programmers, certainly not to anybody else]
I've just found pycallgraph, which makes it easy to visualize the structure of function calls within python code.
This is immensely useful for debugging, and for getting a feel for the structure of a program. It's something you could theoretically already do with epydoc and a profiler, but that's always seemed like a lot of work for little return.
With pycallgraph, it takes a couple of lines:
1 import pycallgraph
2 pycallgraph.start_trace()
3 #...code to be graphed goes here
4 pycallgraph.make_dot_graph('test.png')
5
That's still a lot of typing, though, when I really only want it for a quick picture of whatever is currently baffling me. pycallgraph have missed an opportunity to rewrite it as a decorator:
1 import pycallgraph
2
3 def callgraph(filename = '/tmp/callgraph.png'):
4 def argwrapper(func):
5 def callwrapper(*args, **kwargs):
6 if callwrapper.already_called:
7 return func(*args, **kwargs)
8 callwrapper.already_called = True
9 pycallgraph.start_trace(reset = False)
10 result = func(*args, **kwargs)
11 pycallgraph.stop_trace()
12 pycallgraph.make_dot_graph(filename)
13 return result
14 callwrapper.already_called = False
15 return callwrapper
16 return argwrapper
This lets me generate a call-graph of any function, by popping a one-line decorator onto it:
1 @callgraph('/tmp/callgraph.png')
2 def myfunc():
3 #code here
The other advantage here is that I generally only want to generate the graph once, when the function is first called. Hence the use of afunction attribute, already_called, as a flag to short-circuit past the call-graph on subsequent runs.
I've just found pycallgraph, which makes it easy to visualize the structure of function calls within python code.
This is immensely useful for debugging, and for getting a feel for the structure of a program. It's something you could theoretically already do with epydoc and a profiler, but that's always seemed like a lot of work for little return.
With pycallgraph, it takes a couple of lines:
1 import pycallgraph
2 pycallgraph.start_trace()
3 #...code to be graphed goes here
4 pycallgraph.make_dot_graph('test.png')
5
That's still a lot of typing, though, when I really only want it for a quick picture of whatever is currently baffling me. pycallgraph have missed an opportunity to rewrite it as a decorator:
1 import pycallgraph
2
3 def callgraph(filename = '/tmp/callgraph.png'):
4 def argwrapper(func):
5 def callwrapper(*args, **kwargs):
6 if callwrapper.already_called:
7 return func(*args, **kwargs)
8 callwrapper.already_called = True
9 pycallgraph.start_trace(reset = False)
10 result = func(*args, **kwargs)
11 pycallgraph.stop_trace()
12 pycallgraph.make_dot_graph(filename)
13 return result
14 callwrapper.already_called = False
15 return callwrapper
16 return argwrapper
This lets me generate a call-graph of any function, by popping a one-line decorator onto it:
1 @callgraph('/tmp/callgraph.png')
2 def myfunc():
3 #code here
The other advantage here is that I generally only want to generate the graph once, when the function is first called. Hence the use of afunction attribute, already_called, as a flag to short-circuit past the call-graph on subsequent runs.
