Last active
April 7, 2022 08:22
-
-
Save jcaesar/99f32936dd0f191d2e5d0eeb465be631 to your computer and use it in GitHub Desktop.
Snippet to paste before your python code to get a call graph
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Place at the head of your main file | |
import sys | |
import atexit | |
def function_identifier(frame): | |
code = frame.f_code | |
name = code.co_name | |
file = code.co_filename | |
return "{}:{}".format(file, name) | |
cg = {} | |
def trace_calls(frame, event, arg): | |
if event != 'call': | |
return | |
if frame.f_code.co_name == "print_calls": | |
return | |
global cg | |
caller_f = frame.f_back | |
yeh = "/opt/foo-demo/" # Wherever your code lives | |
nyeh = "<frozen importlib." | |
if frame.f_code.co_filename.startswith(nyeh): | |
return | |
while caller_f.f_back is not None and str(caller_f.f_code.co_filename).startswith(nyeh): | |
caller_f = caller_f.f_back | |
if caller_f.f_code.co_filename.startswith(nyeh): | |
return | |
callee = function_identifier(frame) | |
caller = function_identifier(caller_f) | |
if (not caller.startswith(yeh)) and (not callee.startswith(yeh)): | |
return | |
if caller in cg: | |
cg[caller].add(callee) | |
else: | |
cg[caller] = {callee} | |
def print_calls(): | |
global gc | |
print() | |
print("digraph G {") | |
print(" rankdir=\"LR\";") | |
for caller, callees in cg.items(): | |
for callee in callees: | |
print(" \"{}\" -> \"{}\"".format(caller, callee)) | |
print("}") | |
sys.settrace(trace_calls) | |
atexit.register(print_calls) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment