Python Debugging
Use when Python code needs interactive debugging: hidden locals, confusing state mutation, failing tests, subprocesses, long-running services, or remote attach.
Choose the smallest debugger that reaches the bad frame:
breakpoint(): local code where source edits are acceptable.
python3 -m pdb: launch from the beginning without editing source.
python3 -m pdb -c continue: stop at an unhandled exception.
debugpy: remote/headless processes, DAP clients, an existing PID, or startup races.
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>
Source-edit attach:
import debugpy
debugpy.listen(("127.0.0.1", 5678))
debugpy.wait_for_client()
debugpy.breakpoint()
Post-mortem inspection:
import pdb
import sys
try:
run()
except Exception:
pdb.post_mortem(sys.exc_info()[2])
raise
pdb commands
- Flow:
n, s, r, c, q.
- Stack and 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>.
- Evaluate or mutate:
!statement; full REPL: interact.
Rules
- Reproduce with the smallest command or test first.
- Disable parallel test workers for pdb; worker pools usually break interactive stdin.
- Keep
debugpy in the active environment. Do not add it as a project dependency unless the project needs it.
- Bind debug servers to
127.0.0.1; expose them only on an isolated network or through a secure tunnel.
- Treat PID attach as process injection. Avoid security-sensitive or production targets unless explicitly approved.
- On Linux, check ptrace and container privileges before changing a target when PID attach fails.
- Before committing, run
rg -n 'breakpoint\\(|pdb\\.set_trace|debugpy\\.' --type py and remove accidental breakpoints.
- Rerun the normal project test gate without the debugger.
1---2name: python-debugpy3description: Debug Python with pdb, breakpoint(), post-mortem inspection, and debugpy remote or headless attach.4---56# Python Debugging78Use when Python code needs interactive debugging: hidden locals, confusing state mutation, failing tests, subprocesses, long-running services, or remote attach.910Choose the smallest debugger that reaches the bad frame:1112- `breakpoint()`: local code where source edits are acceptable.13- `python3 -m pdb`: launch from the beginning without editing source.14- `python3 -m pdb -c continue`: stop at an unhandled exception.15- `debugpy`: remote/headless processes, DAP clients, an existing PID, or startup races.1617## Commands1819```bash20python3 -m pdb path/to/script.py arg121python3 -m pdb -c continue path/to/script.py22python3 -c "import debugpy" || python3 -m pip install debugpy23python3 -m debugpy --listen 127.0.0.1:5678 --wait-for-client path/to/script.py24python3 -m debugpy --listen 127.0.0.1:5678 --wait-for-client -m package.module25python3 -m debugpy --listen 127.0.0.1:5678 --pid <pid>26```2728Source-edit attach:2930```python31import debugpy3233debugpy.listen(("127.0.0.1", 5678))34debugpy.wait_for_client()35debugpy.breakpoint()36```3738Post-mortem inspection:3940```python41import pdb42import sys4344try:45 run()46except Exception:47 pdb.post_mortem(sys.exc_info()[2])48 raise49```5051## pdb commands5253- Flow: `n`, `s`, `r`, `c`, `q`.54- Stack and source: `w`, `u`, `d`, `a`, `l`, `ll`.55- Values: `p expr`, `pp expr`, `display expr`.56- Breakpoints: `b file.py:42`, `b func`, `b file.py:42, condition`, `cl <num>`.57- Evaluate or mutate: `!statement`; full REPL: `interact`.5859## Rules6061- Reproduce with the smallest command or test first.62- Disable parallel test workers for pdb; worker pools usually break interactive stdin.63- Keep `debugpy` in the active environment. Do not add it as a project dependency unless the project needs it.64- Bind debug servers to `127.0.0.1`; expose them only on an isolated network or through a secure tunnel.65- Treat PID attach as process injection. Avoid security-sensitive or production targets unless explicitly approved.66- On Linux, check ptrace and container privileges before changing a target when PID attach fails.67- Before committing, run `rg -n 'breakpoint\\(|pdb\\.set_trace|debugpy\\.' --type py` and remove accidental breakpoints.68- Rerun the normal project test gate without the debugger.