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.
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.
When execution stops, common commands are:
- '
nfor next line' - '
sfor step into a function call' - '
cfor continue' - '
p variable_nameto print a value' - '
lto list nearby source lines' - '
qto 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.
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:
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.
At the prompt, you can run:
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.
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:
- add logging to narrow down the failure area
- reproduce locally
- 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.
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, andq. - 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
- How to stop a looping thread in Python?
- How to stop Python Kafka Consumer in program?
- how to store numpy arrays as tfrecord?
- How to stratify the training and testing data in Scikit-Learn?
- How to stop a flink streaming job from program
- How to stop all the running threads, if one of those throws an Exception?
- How to structure Machine Learning projects using Object Oriented programming in Python?
- How to subscribe to a list of multiple kafka wildcard patterns using kafka-python?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack 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.