Python Debugpy
Use when Python code needs interactive debugging: hidden locals, confusing state mutation, failing tests, subprocesses, long-running services, or remote/headless attach.
Pick the smallest debugger that reaches the bad frame.
Choose
breakpoint(): local code, source edits ok, fastest path.
python3 -m pdb: no source edit, launch from the beginning.
python3 -m pdb -c continue: stop at an unhandled exception.
debugpy: remote/headless process, DAP client, already-running PID, or service startup race.
Commands
python3 -m pdb path/to/script.py arg1
python3 -m pdb -c continue path/to/script.py
python3 -c "import debugpy" || python3 -m pip install debugpy
python3 -m debugpy --listen 127.0.0.1:5678 --wait-for-client path/to/script.py
python3 -m debugpy --listen 127.0.0.1:5678 --wait-for-client -m package.module
python3 -m debugpy --listen 127.0.0.1:5678 --pid <pid>
For source-edit attach:
import debugpy
debugpy.listen(("127.0.0.1", 5678))
debugpy.wait_for_client()
debugpy.breakpoint()
For post-mortem:
import pdb, sys
try:
run()
except Exception:
pdb.post_mortem(sys.exc_info()[2])
raise
pdb
- Flow:
n, s, r, c, q.
- Stack/source:
w, u, d, a, l, ll.
- Values:
p expr, pp expr, display expr.
- Breakpoints:
b file.py:42, b func, b file.py:42, condition, cl <num>.
- Mutate/evaluate:
!statement; full REPL: interact.
Rules
- Reproduce with the smallest command/test first.
- Disable parallel test workers for pdb; interactive stdin usually breaks inside worker pools.
- Keep
debugpy in the active env; do not add it as a project dependency unless the project already wants it.
- Bind debug servers to
127.0.0.1; do not expose 0.0.0.0 unless isolated or tunnelled.
- Use unique ports for parallel sessions.
- Treat
debugpy --pid as injection; avoid security-sensitive or production targets unless explicitly approved.
- If PID attach fails on Linux, check ptrace/container privileges before changing the target.
- Cleanup before commit:
rg -n 'breakpoint\\(|pdb\\.set_trace|debugpy\\.' --type py.
- Rerun the normal project test/gate without the debugger.
PYTHONBREAKPOINT=0 disables breakpoint().
- If a process is stuck after debugger detach, confirm it is not still paused at a breakpoint.
1---2name: python-debugpy3description: Debug Python with pdb, breakpoint(), post-mortem inspection, and debugpy remote attach.4---56# Python Debugpy78Use when Python code needs interactive debugging: hidden locals, confusing state mutation, failing tests, subprocesses, long-running services, or remote/headless attach.910Pick the smallest debugger that reaches the bad frame.1112## Choose1314- `breakpoint()`: local code, source edits ok, fastest path.15- `python3 -m pdb`: no source edit, launch from the beginning.16- `python3 -m pdb -c continue`: stop at an unhandled exception.17- `debugpy`: remote/headless process, DAP client, already-running PID, or service startup race.1819## Commands2021```bash22python3 -m pdb path/to/script.py arg123python3 -m pdb -c continue path/to/script.py24python3 -c "import debugpy" || python3 -m pip install debugpy25python3 -m debugpy --listen 127.0.0.1:5678 --wait-for-client path/to/script.py26python3 -m debugpy --listen 127.0.0.1:5678 --wait-for-client -m package.module27python3 -m debugpy --listen 127.0.0.1:5678 --pid <pid>28```2930For source-edit attach:3132```py33import debugpy3435debugpy.listen(("127.0.0.1", 5678))36debugpy.wait_for_client()37debugpy.breakpoint()38```3940For post-mortem:4142```py43import pdb, sys4445try:46 run()47except Exception:48 pdb.post_mortem(sys.exc_info()[2])49 raise50```5152## pdb5354- Flow: `n`, `s`, `r`, `c`, `q`.55- Stack/source: `w`, `u`, `d`, `a`, `l`, `ll`.56- Values: `p expr`, `pp expr`, `display expr`.57- Breakpoints: `b file.py:42`, `b func`, `b file.py:42, condition`, `cl <num>`.58- Mutate/evaluate: `!statement`; full REPL: `interact`.5960## Rules6162- Reproduce with the smallest command/test first.63- Disable parallel test workers for pdb; interactive stdin usually breaks inside worker pools.64- Keep `debugpy` in the active env; do not add it as a project dependency unless the project already wants it.65- Bind debug servers to `127.0.0.1`; do not expose `0.0.0.0` unless isolated or tunnelled.66- Use unique ports for parallel sessions.67- Treat `debugpy --pid` as injection; avoid security-sensitive or production targets unless explicitly approved.68- If PID attach fails on Linux, check ptrace/container privileges before changing the target.69- Cleanup before commit: `rg -n 'breakpoint\\(|pdb\\.set_trace|debugpy\\.' --type py`.70- Rerun the normal project test/gate without the debugger.71- `PYTHONBREAKPOINT=0` disables `breakpoint()`.72- If a process is stuck after debugger detach, confirm it is not still paused at a breakpoint.