I want to closely monitor the chain of function calls which are called from a certain function.
import pdb; pdb.set_trace()
res = api.InsertVideoEntry(video_entry, video)
I'm looking for a way to easily see that api.insertVideoEntry(video_entry, video)
calls foo()
which calls bar()
which calls baz()
,
Here's a really crude diagram to show what I mean. I don't need it in this form, but this is the kind kind of information I'm looking for.
api.insertVideoEntry()
foo()
bar()
baz()
baz2()
log()
finish()
This was an interesting learning experience to write up. Maybe you can use the code shown here? This demonstration 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 demo, you might like this variation with a called arguments readout:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With