Function_trace is a simple debugging library, inspired by similar libs in Common Lisp and Clojure. It captures function call arguments and return values, and prints them in a nested fashion so you can easily see which function is being called by which other function, what arguments it was called with, and what its return value was.
Trace blocks of code with the trace_on
context manager. It
accepts one positional argument, a list of modules and classes to be
traced. When a class is traced, that includes all the methods defined
in that class, but not inherited methods. When a module is traced,
that includes all the functions in that module, but does not include
any class methods defined in that module (you must specify the class
separately).
By default, the trace output is printed to stdout. You can modify
this behavior by replacing function_trace.tracer
with a function
that does whatever you like with the trace. The tracer function
should have the signature (f, *args, **kwargs)
which is the
function to trace, and the arguments to call the function with. It
should call the function with the args at some point. Note it is
preferable to catch any exceptions thrown by f, log them and re-raise
the exception.
include_hidden
if set to True, also trace functions whose name starts with_
. Note, the__repr__
function will never be traced.
from function_trace import trace_on with trace_on([Class1, module1, Class2, module2], include_hidden=True): module1.function1("arg1", "arg2", option=True) x = new Class1() x.method1(arg1, arg2)
- module1.function1("arg1", "arg2", option=True) | - module1.function2("arg2") | | - module1.check_thing() | | -> True | -> "myresult" -> "myresult" - Class1.x(<Class1 object at 0xdeadbeef>, "arg1val", "arg2val") | - module2.function1("arg2val") | -> "foo" | - Class2.y(<Class2 object at 0xabcd0001>, "arg1val") | -> BadInputException("You can't call y with 'arg1val'!") -> BadInputException("You can't call y with 'arg1val'!")
- Methods will show the first argument
self
. By default, arguments and return values are printed usingrepr
, so if you want to see something more informative than<Class1 object at 0xdeadbeef>
, you can define__repr__
onClass1
to print whatever you like (probably the values of various fields of that object). - By default, exceptions that are raised by a function are printed as its return value. This makes it possible to see an exception propagating down the stack. It is currently not possible to distinguish between a function call that returns an exception object, and one that raises that exception object (but functions that intentionally return Exceptions are rare anyway).