How can I take a step to use the python debugger to break with every function call?

I want to closely monitor the chain of function calls called from a specific function.

import pdb; pdb.set_trace() res = api.InsertVideoEntry(video_entry, video) 

I am looking for a way to easily see that api.insertVideoEntry(video_entry, video) calls foo() , which calls bar() , which calls baz() ,

Here is a really rough chart to show what I mean. I do not need this in this form, but this is exactly what I am looking for.

 api.insertVideoEntry() foo() bar() baz() baz2() log() finish() 
+4
source share
1 answer

It was an interesting learning experience for writing. Maybe you can use the code shown here? This demo should give you an idea of ​​the type of output you can expect when using trace .

 # Functions to trace # ================== def baz(): pass def baz2(): pass def bar(): baz() baz2() def log(): pass def foo(): bar() log() def finish(): pass def insertVideoEntry(): foo() finish() # Names to trace # ============== names = list(locals()) # Machinery for tracing # ===================== import os import sys def trace(start, *names): def tracefunc(frame, event, arg): if event == 'call': code = frame.f_code name = code.co_name if name in names: level = -start while frame: frame = frame.f_back level += 1 print('{}{}.{}()'.format( ' ' * level, os.path.splitext(os.path.basename(code.co_filename))[0], name)) return tracefunc sys.settrace(tracefunc) # Demonstration of tracing # ======================== trace(2, *names) insertVideoEntry() 

If you are interested in a recursive demonstration, you might like this option with the named arguments shown:

 import os import sys def main(discs): a, b, c = list(range(discs, 0, -1)), [], [] line = '-' * len(repr(a)) print(a, b, c, sep='\n') for source, destination in towers_of_hanoi(discs, a, b, c): destination.append(source.pop()) print(line, a, b, c, sep='\n') def towers_of_hanoi(count, source, via, destination): if count > 0: count -= 1 yield from towers_of_hanoi(count, source, destination, via) yield source, destination yield from towers_of_hanoi(count, via, source, destination) def trace(start, *names): def tracefunc(frame, event, arg): if event == 'call': code = frame.f_code name = code.co_name if name in names: level = -start args = ', '.join(repr(frame.f_locals[name]) for name in code.co_varnames[:code.co_argcount]) while frame: frame = frame.f_back level += 1 print('{}{}.{}({})'.format( ' ' * (level * 4), os.path.splitext(os.path.basename(code.co_filename))[0], name, args)) return tracefunc sys.settrace(tracefunc) if __name__ == '__main__': trace(3, 'main', 'towers_of_hanoi') main(3) 
+3
source

All Articles