Stop debugging Python with print

Even though breakpoint() has been available since Python 3.7, many developers still reach for print to debug. Maybe out of habit or fear. Here is a quick example to get you started.

Suppose you have a shopping cart and want to calculate the total, applying a discount. You might write something like this:

def calculate_total(items):
    total = 0
    for item in items:
        breakpoint() # Execution will stop here
        total += item["price"] * item["quantity"]
    return total

When execution reaches that line, the program stops and gives you a (Pdb) prompt. From there you can:

  • Inspect variables: p item, p total
  • Step line by line: n (next)
  • Step into functions: s (step)
  • Continue to the next breakpoint: c (continue)
  • Exit the debugger: q (quit)

You can also run any valid Python expression, modify variables, call functions, and so on.

Three ways to run the script

Normal execution

To debug, run the script as usual. The program will stop at the first breakpoint() and open the interactive (Pdb) console:

uv run demo.py

Ignore all breakpoints

The script runs straight through without pausing. Useful when you have finished debugging but have not removed the breakpoint() calls yet, or when running in a production environment.

PYTHONBREAKPOINT=0 uv run demo.py

Post-mortem mode

Useful for scripts that have no breakpoint() calls. The script runs normally and, if something crashes, drops you into the pdb console at the exact point of failure so you can inspect the state.

uv run python -m pdb -c continue demo.py

Commands

Command Action
n (next) execute the current line without stepping into functions
s (step) same, but steps into the called function
c (continue) resume until the next breakpoint or the end
l (list) show the code around the current line
p expr print a variable or expression: p total
pp expr same but pretty-printed, useful for dicts and lists
w (where) show the call stack
a (args) show the arguments of the current function
r (return) execute until the current function returns
q (quit) abort execution
h (help) general help; h <command> for details on a specific one

Final notes

The benefits of using breakpoint() and pdb are clear:

  • It keeps the code clean, no print statements to remove afterwards.
  • You can inspect the program state at any point.
  • You can modify variables and test changes on the fly.
  • You can pause execution at any moment, not just when something crashes.

And it is a standard Python tool, no installation required.

Give it a try and see how it improves your workflow.

Happy debugging!

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Will you buy me a coffee?

Comments

There are no comments yet.

Written by Andros Fenollosa

June 19, 2026

2 min of reading

You may also like

Visitors in real time

You are alone: 🐱