Debugging Tools

Libraries for debugging code.

Stepping through code in ipdb gets you pdb with IPython's tab completion. Python debugging tools cover slow code too: py-spy profiles a running Python program.

How to choose:

  • pdb with tab completion and syntax highlighting: ipdb
  • Finding where a running program spends its time, without changing it: py-spy
  • A full-screen debugger in your terminal: PuDB
  • A timeline of every function call: VizTracer
  • Memory use and leaks, native extensions included: Memray
  • A readable call tree of where your script spends wall-clock time: pyinstrument
  • CPU, GPU, and memory use, line by line: Scalene
  • SQL queries and request data on Django pages: Django Debug Toolbar
  • Every Django request and its SQL queries, recorded to inspect later: Silk
  • Print debugging that labels each value: IceCream
  • The same toolbar on Flask pages: Flask-DebugToolbar

Listed in editorial order, grouped by use case. Click a column header to re-sort the whole list.

Press / to search. Tags open their category. Click a row for details.

Search and filter

Results

Row number Tags

pdb-like Debugger 2 projects

IPython-enabled pdb.
gotcha/github.com/gotcha/ipdb /1,976 stars /
A full-screen, console-based Python debugger.
inducer/github.com/inducer/pudb /3,250 stars /

Tracing 1 project

A low-overhead tool that traces and visualizes Python code execution.

Profiler 4 projects

A sampling profiler for Python programs. Written in Rust.
benfred/github.com/benfred/py-spy /15,613 stars /
Tracks memory allocations in Python code, native extensions, and the interpreter itself.
bloomberg/github.com/bloomberg/memray /15,401 stars /
A statistical wall-clock profiler with low overhead and readable call-tree output.
joerick/github.com/joerick/pyinstrument /8,021 stars /
A high-performance, high-precision CPU, GPU, and memory profiler for Python.
plasma-umass/github.com/plasma-umass/scalene /13,536 stars /

Others 4 projects

Display various debug information for Django.
Live profiling and inspection of HTTP requests and database queries for Django.
jazzband/github.com/jazzband/django-silk /4,994 stars /
Inspect variables, expressions, and program execution with a single, simple function call.
gruns/github.com/gruns/icecream /10,110 stars /
A port of the django-debug-toolbar to Flask.

Debugging Tools guide

ipdb gives you IPython's debugger, with tab completion, syntax highlighting, and better tracebacks, behind the same interface as pdb. Drop into it with import ipdb; ipdb.set_trace(), or call ipdb.pm() for post-mortem debugging after an exception.

py-spy is a sampling profiler that shows what a program spends its time on without restarting it or modifying its code. It runs outside the profiled process, which makes it safe to use on production code. py-spy record writes a flame graph of a process ID or a command you hand it, and py-spy dump prints the call stack where a program is hung.

PuDB keeps the source, the stack, breakpoints, and variables all visible at once in one full-screen terminal view. Start it from your code with from pudb import set_trace; set_trace(), or run a whole script with python -m pudb my-script.py.

VizTracer records every function's entry and exit time across a whole run, which helps catch sporadic performance issues. Run your script with viztracer my_script.py instead of python, then open the result.json it writes with vizviewer.

Memray tracks allocations in Python code, native extension modules, and the interpreter itself, to find memory leaks and the code behind high memory use. Profiling takes two steps: memray run saves the allocations to a file, then memray flamegraph builds a report from it.

pyinstrument measures wall-clock time, so time spent downloading data, reading files, and talking to databases counts too. Type pyinstrument script.py instead of python script.py, or wrap a block in with pyinstrument.profile():.

Scalene profiles CPU, GPU, and memory line by line and per function. It separates time in Python from time in native code, so you can focus on code you can change. Run scalene run your_prog.py, then scalene view opens the profile in your browser.

Django Debug Toolbar adds panels to your pages for the current request's SQL queries, templates, cache calls, and more. Its setup adds the app, its URLs, and its middleware, and shows the toolbar only to IP addresses in INTERNAL_IPS.

Silk intercepts and stores HTTP requests and database queries, then shows them in its own UI: each request's time, query count, headers, and bodies. Its setup adds its middleware and app to your settings, includes silk.urls in your URLconf, and runs migrate. The UI then lives at /silk/.

IceCream's ic() prints each expression along with its value. With no arguments, it prints the file, line, and function it runs in. Since ic() returns its arguments, you can wrap an expression in existing code without rewriting the line.

Flask-DebugToolbar is a port of Django Debug Toolbar to Flask. Wrap your app in DebugToolbarExtension(app), and the toolbar shows up in HTML responses while debug mode is on.

Both debuggers also open from the built-in breakpoint(): set the PYTHONBREAKPOINT environment variable to ipdb.set_trace or pudb.set_trace. Among profilers, sampling ones like py-spy, pyinstrument, and Scalene cost much less overhead than tracing ones, while a tracer like VizTracer records every call and gives you more information.

Know a project that belongs here?

Tell us what it does and why it stands out.