Debugging legacy Python without losing a week
pdb, coverage, and a disciplined git bisect turn a scary codebase into a solvable Sunday afternoon.
Instructors
Mandola AI
You've inherited a Python codebase. It has no tests, sparse comments, and a README that just says "run it." The good news: it's Python, so you can read it. The bad news: you have no idea which part is broken, and your client needs it fixed by Friday.
Here's the systematic approach that works.
Step 1: Understand the failure
Before you touch any code, reproduce the bug. Write down the exact steps. If you can't reproduce it, you can't fix it. If the reproduction steps are flaky, fix that first. A reliable reproduction is worth a thousand lines of code reading.
Step 2: git bisect
If you know the bug is new, use git bisect. Mark a known-good commit and the current broken state. Let binary search do the work. In 10 steps, you can narrow down which commit introduced the bug across 1,000 commits.
This is the most underused tool in debugging. Stop reading code linearly. Let the computer find the problem for you.
Step 3: pdb strategically
Don't scatter print statements everywhere. Set breakpoints at the entry point of the failing function and at the point where the output diverges from expectations. Use pdb's interact command to explore the state at each breakpoint.
Ask yourself: what do I expect this variable to be? What is it actually? The gap between expectation and reality is where the bug lives.
Step 4: coverage as a map
Run the test suite with coverage.py. The lines that aren't covered are the lines you don't understand. Focus your investigation on untested code paths — that's where legacy bugs hide.
Coverage isn't just a metric. It's a debugging tool that shows you where the codebase is blind.
Step 5: isolate and fix
Once you've found the bug, write a minimal test that reproduces it. Fix the bug. Verify the test passes. Then write a few more tests around the area to make sure you haven't broken anything else.
The whole process should take hours, not days. The discipline is in the sequence: reproduce, bisect, debug, cover, fix. Skip steps and you'll waste a week.
Continue reading
Why we teach a Python-first AI stack in 2026
FastAPI + Pydantic + pgvector is boring on purpose. Here's the shape of a career-ready AI stack that survives production.
From tutorial to paycheck: the 90-day rewire
The three feedback loops we use to turn beginners into billable engineers — proposals, portfolios, and pull requests.
RAG that actually ships: what changes past 10k docs
Chunking, hybrid search, eval harnesses. A quiet checklist for the moment your prototype meets real data.
Want to go deeper?
Join the next Mandola cohort.
Small groups. Weekly live sessions. Code reviews from engineers who ship Python for a living. Applications open on a rolling basis.