I'm working on a project with lots of calls to functions stored as callable instances and my only way to "debug" is writing on stdout. Also the project is massively nested and monolithic so to see what's going on by just adding print/logging statements leads to massive confusing output which - in the best case - just tells me where to place the next statement.
Since I can't easily change that situation I wonder if it's possible to get a readable call tree (with functions, files and arguments) from one specific call (rather than letting Python print all calls which results in millions of lines which don't tell me much).
Great would be something like:
with function_call_tracer():
result = tree.handler_fn()(args)
producing something like
result = tree.handler_fn()(args=(1,2,3)) [<bound method foo.handler_fn of <Bar object at 0x7fe7748a9610>>]
> do_something(v=(1,2,3)) [<function do_something at 0x7fe778748a96>]
> > calc1(a=1)) [<calc1 do_something at 0x7fe577748a96>]
> > calc2(a=2)) [<calc2 do_something at 0x7fe756748a67>]
> > calc3(a=3)) [<calc3 do_something at 0x7dfe77435a78>]
> ...
> > ...
> > > ...
I know there is the trace module
import trace, sys
tracer = trace.Trace(trace=1, count=1)
tracer.runfunc(lambda: ruleset.valuespec().transform_value(param_copy)) \
.results() \
.write_results(show_missing=True, coverdir=".")
ant there are pdb, sys.set_trace and more - but I didn't figure out yet how to extract the information what function called what other function using what arguments in a way I can activate somewhere in the code and deactivate it afterwards.
Maybe I just use them not as intended - how would you get a call tree from a function call containing arguments?