Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Python

Debugging Python with pdb and breakpoint()

Learn how to debug Python code efficiently using pdb and the modern breakpoint() function, with practical examples and tips from real-world PythonSkillset projects.

July 2026 8 min read 1 views 0 hearts

Here's the article for PythonSkillset.com:

Debugging Python with pdb and breakpoint(): Your Code's Best Friend

Ever spent hours staring at your screen wondering why a variable turned into None or why your loop skipped every third element? I've been there too. Instead of adding ten thousand print() statements and hoping for the best, there's a better way. Let's talk about pdb and breakpoint().

Why I Stopped Using Print Statement Debugging

Back when I was building my first web scraper for PythonSkillset.com, I had a function that kept crashing halfway through parsing HTML. I added prints everywhere. The output was a mess of text mixed with actual data. It took me three hours to find one misplaced variable assignment. That's when I finally learned to debug properly.

Meet pdb: Python's Built-in Debugger

pdb stands for "Python Debugger." It's been in Python since version 2.1, and it's included with every Python installation. No pip install needed.

Basic usage starts with importing it:

import pdb

def calculate_average(numbers):
    pdb.set_trace()  # Execution stops here
    total = sum(numbers)
    avg = total / len(numbers)
    return avg

result = calculate_average([10, 20, 30, 40])

When your code hits pdb.set_trace(), execution pauses, and you get an interactive prompt. Here are the commands you'll use most:

Command What It Does
n (next) Execute current line, stop at next
c (continue) Run until next breakpoint
s (step) Step into a function call
q (quit) Exit the debugger
p variable_name Print the value of a variable
l (list) Show code around current line

The Modern Way: breakpoint() in Python 3.7+

Python 3.7 introduced breakpoint(), which is a cleaner alternative. It does exactly what pdb.set_trace() does, but with less typing:

def process_user_data(user_list):
    breakpoint()  # Same as pdb.set_trace()
    active_users = [u for u in user_list if u['active']]
    email_list = [u['email'] for u in active_users]
    return email_list

Using breakpoint() has an extra advantage: you can disable all breakpoints globally by setting the PYTHONBREAKPOINT=0 environment variable. Your code runs without pausing even though breakpoint() calls remain.

A Real Debugging Session from PythonSkillset.com

Here's a scenario we actually ran into on our site. We had a function that should calculate the total time spent by users reading articles:

def calculate_reading_time(articles):
    breakpoint()  # Let's see what's happening
    total_minutes = 0
    for article in articles:
        total_minutes += article['reading_time_minutes']

    average = total_minutes / len(articles)
    return average

# Data from our database
article_data = [
    {'title': 'Python Decorators', 'reading_time_minutes': 8},
    {'title': 'List Comprehensions', 'reading_time_minutes': 6},
    {'title': 'Error Handling', 'reading_time_minutes': None}  # Oops! Bug source
]

When breakpoint() fires, here's how you'd investigate:

  1. Type p articles to inspect the list — notice one has reading_time_minutes as None
  2. Use n to step through the loop, watching total_minutes
  3. When it hits the None value, Python would crash with a TypeError
  4. Type p article to see which item caused the error
  5. Fix the issue: skip None values or convert them to 0

Practical Tips for Everyday Debugging

Setting breakpoints manually works, but here's what I do for larger projects at PythonSkillset:

Conditional breakpoints: Want to stop only when a variable meets a condition?

for i in range(100):
    if i == 42:
        breakpoint()  # Only pauses at iteration 42
    process_data(i)

Debug in loops with minimal clutter: Instead of breaking inside a loop (which pauses each iteration), use

for i, item in enumerate(dataset):
    if i % 50 == 0:
        print(f"Processing item {i}")  # Quick status, no break
    if some_condition:  
        breakpoint()  # Only when needed

Post-mortem debugging: When your script crashes, you can enter pdb after the error:

python -m pdb my_script.py

Then type continue to let it run. When it crashes, pdb stops at the error line, and you can inspect variables.

When breakpoint() Won't Cut It

For beginners, breakpoint() handles 90% of debugging needs. But if you're working with:

  • Multi-threaded applications (threads confuse pdb)
  • GUI applications (the pdb prompt blocks the interface)
  • Very large data processing (stepping through billions of items is impractical)

...then you might need IDE debuggers (PyCharm, VS Code) or logging frameworks.

Common Mistakes I Still Make

Even after years of debugging, I still trip over these:

  1. Forgetting to remove breakpoints in production: Always run code reviews checking for stray breakpoint() calls. One time I pushed code to our live PythonSkillset.com server, and the entire site paused for a debugging session nobody wanted.

  2. Assuming breakpoint() works in all environments: On some CI/CD servers, pdb input isn't available. Your tests might hang forever. Use environment variables to conditionally enable breakpoints.

  3. Not knowing when to step vs. next: If you're inside a loop and call s on a function, you'll dive into that function's code. Sometimes you want n to skip over the function entirely. Get comfortable with the difference; it saves time.

The Debugger Mindset

Debugging isn't about finding the problem — it's about understanding your code's actual behavior versus what you think it should do. Every time I hit a bug at PythonSkillset, I remind myself: the computer is always right. It's executing exactly what you told it to. The debugger shows you what that actually means.

Start with breakpoint(). Keep pdb commands handy. And for heaven's sake, stop printing everything. Your future self will thank you.

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.