Denis
Denis

Reputation: 3707

How to get function stack trace for any function?

For example, I have the following code:

def m1(num):
    pass


def m2(num):
    pass


def foo(num):
    m2(num)


def foo2(num):
    foo(num)
    m1(num)

def main():
    foo2(1)


if __name__ == "__main__":
    main()

Is there a way to get call list for each function? For example, for this example I want to get the following dict:

main: foo2
foo2: foo, m1
foo: m2
m2: 
m1: 

I know only one way to complete my task. It is to use globals() and then parse source code. But it seems is very ugly.

Upvotes: 0

Views: 162

Answers (1)

abarnert
abarnert

Reputation: 365607

I know only one way to complete my task. It is to use globals() and then parse source code. But it seems is very ugly.

I'm not sure what you think parsing source code would do for you here.


If you want to build a dynamic call graph, what you want to do is decorate each function—replace it with a wrapper that does some extra stuff before or after calling the real function. For example:

def wrapper(func):
    @functools.wraps
    def wrap(*args, **kwargs):
        # do stuff to update call graph
        return func(*args, **kwargs)
    return wrap

g = globals()
for name, value in g.items():
    if callable(value):
        g[name] = wrapper(value)

Or, maybe more simply (and more flexibly), you might want to use the bdb debugger framework to step through your program and just record the user_call instances.


If you want to build a static call graph, then obviously that comes from the source, but there's no reason to parse it yourself when Python comes with the ast module to do it for you. (You can use inspect.getsource to get the source code to parse.)

Upvotes: 1

Related Questions