Highlights

Subscribe

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 4.25

« Opening up a tax haven | Main | Resolver One »

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.