Debug Python with Bugsaur¶
Adapter: debugpy
Install the adapter¶
debugpy is a Python module, so it is installed into the interpreter that runs
your code — usually the project virtualenv, not the system Python:
Configure¶
bugsaur init detects the project by pyproject.toml, setup.py or
requirements.txt, and writes one profile per entry point it finds: main.py,
app.py, manage.py, __main__.py in the root, and src/<pkg>/__main__.py.
It also looks for .venv/bin/python and venv/bin/python in the project root.
When it finds one, both the adapter and the debuggee are pointed at that
interpreter.
version = 1
default = "main"
[profiles.main]
adapter = "debugpy"
adapter_command = "${root}/.venv/bin/python"
program = "main.py"
[profiles.main.launch_arguments]
python = "${root}/.venv/bin/python"
[profiles.shop]
adapter = "debugpy"
adapter_command = "${root}/.venv/bin/python"
program = "src/shop/__main__.py"
[profiles.shop.launch_arguments]
python = "${root}/.venv/bin/python"
Note the two separate settings — they are not redundant:
adapter_command— which interpreter runs the adapter;launch_arguments.python— which interpreter runs your code.
With no virtualenv both fall back to python3 from PATH, which then needs
debugpy installed in it.
cwd is not written: the working directory is the project root anyway, and that
is exactly what makes imports of a package under src/ resolve.
Django¶
[profiles.web]
adapter = "debugpy"
adapter_command = "${root}/.venv/bin/python"
program = "manage.py"
args = ["runserver", "--noreload", "8000"]
env_file = ".env"
--noreload is required
Django's autoreloader starts a second process, and the debugger is not attached to it. Breakpoints in a reloaded worker never fire, and it looks like the debugger is broken rather than that there are two processes.
Debug a module instead of a file¶
debugpy accepts module. There is no dedicated profile field for it, but the
escape hatch works:
[profiles.tests]
adapter = "debugpy"
program = "."
args = ["-x", "tests/"]
[profiles.tests.launch_arguments]
module = "pytest"
pytest¶
The recipe above debugs a whole run. To debug the single test under your cursor, no profile is needed:
Bugsaur runs the selected pytest node through debugpy, inheriting the adapter,
environment and working directory from the profile. See
Guides → Debug pytest.
An entry point outside the root and outside src/¶
A layout like services/api/app.py is not found by detection — zero profiles,
and the launch stops. Write it by hand:
Diagnostics¶
| Symptom | Likely cause | Where to look |
|---|---|---|
No module named debugpy |
installed into a different interpreter than the one running | install into the venv, check adapter_command |
| Breakpoints never fire in Django | the autoreloader forked a second process | add --noreload |
ImportError for your own package |
the working directory is not what the code assumes | Working directory |
| Stops in library code, not yours | the exception was raised deeper | Call Stack |
| Session never starts | the interpreter path in adapter_command is wrong |
Adapter fails to start |