Python
Debugging
Code Debugging
Step-by-Step Debugging
Programming Tips

How to step through Python code to help debug issues?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Stepping through Python code is one of the fastest ways to understand why a program behaves differently from what you expected. Instead of guessing from logs alone, a debugger lets you pause execution, inspect variables, and move through the code one line at a time. The key tools in Python are the built-in debugger pdb, the breakpoint() helper, and debugger support in IDEs such as VS Code or PyCharm.

Start with breakpoint()

In modern Python, the easiest way to pause execution is breakpoint(). When the interpreter hits that line, it opens the debugger in the terminal.

python
1def divide(a, b):
2    breakpoint()
3    return a / b
4
5print(divide(10, 2))

When execution stops, common commands are:

  • 'n for next line'
  • 's for step into a function call'
  • 'c for continue'
  • 'p variable_name to print a value'
  • 'l to list nearby source lines'
  • 'q to quit debugging'

This is usually enough to inspect a small bug quickly without changing your environment.

Using pdb Explicitly

breakpoint() is a thin wrapper. You can also import pdb directly, which is useful when reading older code or when you want a more explicit dependency.

python
1import pdb
2
3def total_price(items):
4    total = 0
5    for item in items:
6        pdb.set_trace()
7        total += item["price"] * item["qty"]
8    return total
9
10items = [
11    {"price": 5, "qty": 2},
12    {"price": 8, "qty": 1},
13]
14
15print(total_price(items))

Inside the debugger, you can inspect the current item, the running total, and the current call stack before advancing to the next iteration.

Step Into, Step Over, and Continue

These three concepts matter more than memorizing every debugger command.

step into follows a function call so you can inspect its internals.

next executes the current line but does not enter called functions.

continue resumes execution until the next breakpoint or program exit.

For example:

python
1def parse_amount(text):
2    return int(text.strip())
3
4def process():
5    raw = " 42 "
6    value = parse_amount(raw)
7    print(value)
8
9process()

If the bug is likely inside parse_amount, use s. If you already trust that function and want to stay in process, use n.

Inspecting State While Paused

The real value of stepping comes from checking live state, not just moving line by line. In pdb, p variable prints a value, while pp variable pretty-prints nested structures.

python
1def build_user():
2    user = {
3        "name": "Ava",
4        "roles": ["admin", "editor"],
5        "active": True,
6    }
7    breakpoint()
8    return user
9
10build_user()

At the prompt, you can run:

text
p user
pp user

You can also evaluate expressions directly, which is useful for checking assumptions without editing the code.

Post-Mortem Debugging for Exceptions

Sometimes the program has already crashed, and you want to inspect the state at the failure point. Python supports post-mortem debugging.

python
1import pdb
2
3def crash():
4    data = {"count": "five"}
5    return int(data["count"])
6
7try:
8    crash()
9except Exception:
10    pdb.post_mortem()

This drops you into the debugger after the exception, which is often better than adding guesses before the failure.

IDE Debuggers

Terminal debugging is powerful, but IDEs make it easier to visualize state. In VS Code or PyCharm you can:

  • click in the gutter to set breakpoints
  • inspect locals and globals in a side panel
  • watch expressions update live
  • step through frames with buttons instead of commands

The underlying workflow is the same. The IDE simply provides a friendlier interface on top of debugging concepts you should still understand.

When Logging Is Better Than Stepping

Do not use an interactive debugger for every problem. If a bug only appears in production, inside a background worker, or under concurrency, structured logging may be more practical. A good debugging workflow usually combines both:

  1. add logging to narrow down the failure area
  2. reproduce locally
  3. step through the reduced case with a debugger

That sequence saves time compared with placing random breakpoints across the codebase.

Debugging Tests

Stepping through failing tests is often cleaner than debugging the full application.

python
1def normalize_name(text):
2    return text.strip().title()
3
4def test_normalize_name():
5    breakpoint()
6    assert normalize_name(" ava ") == "Ava"

Run the test file directly or under your test runner, and the debugger will pause where the assertion is about to execute. This is especially useful when fixtures or test data transformations are involved.

Common Pitfalls

The most common mistake is stepping through too much code without first identifying a narrow reproduction case. Another issue is using next when you really need step, which causes you to skip over the function where the bug lives. Developers also forget to inspect state after every important line and end up “driving” the debugger without learning anything. Finally, leaving breakpoint() in committed code can disrupt test runs or background jobs, so remove it once the investigation is complete.

Summary

  • Use breakpoint() for the quickest way to pause Python execution.
  • Learn the core commands: n, s, c, p, and q.
  • Inspect variable state while paused instead of only advancing through lines.
  • Use post-mortem debugging when the program has already crashed.
  • Combine logging and stepping for faster, more focused debugging.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.