Advanced·12 min·engineering · debugging · pdb
Debugging Python like a pro
Debugging: know your tools before you need them
Prints are fine. Real debugging is faster.
breakpoint() — the modern entry point
Since Python 3.7, breakpoint() drops you into pdb at that line:
def process(items):
for it in items:
breakpoint() # program pauses here in your terminal
...
Env var PYTHONBREAKPOINT=ipdb.set_trace or =0 switches or disables globally.
pdb commands you actually need
nnext line (step over)sstep into functionccontinue until next breakpointllist source around herep xprint a valuepp dpretty-printwwhere (stack)u/dup / down the stackqquit
Post-mortem debugging
When something crashes in production logs, launch:
python -m pdb script.py
Or programmatically pdb.post_mortem() after catching.
Reading tracebacks
Bottom-up:
- Last line = exception type + message.
- Above = where the exception was raised (deepest frame).
- Higher = who called them. Skip framework noise. Look for your file paths first.
Logging beats print for real projects
import logging
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(name)s: %(message)s")
log = logging.getLogger(__name__)
log.info("processing %d items", len(items))
- Levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.
- Configurable per-module without touching call sites.
- Structured logs (
extra={...}) → readable by log aggregators.
Try it
- Fix the bug in the starter code (
processshouldn't add negatives). - Add a logger and log a WARNING when a negative is skipped.