Package: nopdb
Installation:pip install nopdbDocs:https://nopdb.readthedocs.io/NoPdb is aprogrammatic(non-interactive)debuggerfor Python. This means it gives you access todebugger-like superpowersdirectly from your code. With NoPdb, you can:capture function calls, including arguments, local variables, return values and stack tracesset “breakpoints”that trigger user-defined actions when hit, namely:evaluate expressionsto retrieve their values laterexecute arbitrary code, including modifying local variablesenter an interactive debuggerlikepdbNoPdb is also a convenient tool for inspectingmachine learning model internals. For example,this notebookandthis post on Towards Data Scienceshow how to use it to visualize Transformer attention in PyTorch.NoPdb should run at least under CPython and PyPy. Most features should work under any implementation
as long as it hassys.settrace().Note:This project is in its early development stage. Contributions and improvement ideas are welcome.Capturing function callsThe functionscapture_call()andcapture_calls()allow
capturing useful information about calls to a given function.
They are typically used as context managers, e.g.:withnopdb.capture_calls(fn)ascalls:some_code_that_calls_fn()print(calls)# see details about how fn() was calledThe information we can retrieve includes the function’s arguments, return value, local variables and stack trace. For example:>>>withnopdb.capture_call(f)ascall:...g(1)>>>callCallCapture(name='f',args=OrderedDict(x=1,y=1),return_value=4)>>>call.print_stack()File"<stdin>",line2,in<module>File"<stdin>",line2,ingFile"<stdin>",line1,inf>>>call.args['x']1>>>call.return_value4>>>call.locals{'y':1,'x':1,'z':2}Setting breakpointsLike conventional debuggers, NoPdb can set breakpoints. However, because NoPdb is anon-interactivedebugger, its breakpoints do not actually stop the execution of the
program. Instead, they allow executing actions scheduled in advance, such as
evaluating expressions.To set a breakpoint, call thebreakpoint()function. A breakpoint object
is returned, allowing to schedule actions using its methods such aseval()andexec(). For example:# Break at line 3 of the file or notebook cell where f is definedwithnopdb.breakpoint(function=f,line=3)asbp:x=bp.eval("x")# Schedule an expressiontype_y=bp.eval("type(y)")# Another onebp.exec("print(y)")# Schedule a print statementsome_code_that_calls_f()print(x,type_y)# Retrieve the captured valuesThere are other ways to specify the breakpoint location. For example:# Break at any line with the given source code in the given filewithnopdb.breakpoint(file="pathlib.py",line="return obj")asbp:...# Break as soon as any function with the given name is calledwithnopdb.breakpoint(function="myfunc")asbp:...Not only can we capture values, we can also modify them!>>>withnopdb.breakpoint(function=f,line=3)asbp:...# Get the value of x, then increment it, then get the new value...x_before=bp.eval('x')...bp.exec('x += 1')...x_after=bp.eval('x')......some_code_that_calls_f()>>>x_before[2]>>>x_after[3]Planned featuresFunctionalities that do not exist, but could be added in the future:Breakpoint.callback()for calling a given callback function, passing information about the current frame as an argument.Breakpoint.jump()for jumping to a different line in the same function.A way to disable breakpoints.LimitationsLike Pdb, NoPdb only works with pure-Python functions. Calls to built-ins and C extensions cannot be captured. This also applies to ML frameworks that compile models into static graphs; for NoPdb to work, this feature needs to be disabled, e.g. withtf.config.run_functions_eagerly(True)in TensorFlow and with thejax.disable_jit()context manager in JAX.Local variable assignment inBreakpoint.exec()is only supported under CPython and PyPy.