An extension for nvim-dap providing default configurations for python and methods to debug individual test methods or classes.
- Requires Neovim >= 0.5
- Requires nvim-dap
- Requires debugpy
- Install like any other neovim plugin:
- If using vim-plug:
Plug 'mfussenegger/nvim-dap-python'
- If using packer.nvim:
use 'mfussenegger/nvim-dap-python'
- If using vim-plug:
If you want to use the test runner functionality, it additionally requires a tree sitter parser for Python.
Options to install debugpy:
- Via a system package manager. For example:
pacman -S python-debugpy
- Via
pip
in avenv
:
mkdir ~/.virtualenvs
cd ~/.virtualenvs
python -m venv debugpy
debugpy/bin/python -m pip install debugpy
Note that the virutalenv used for the debugpy
can be independent from any
virtualenv you're using in your projects.
nvim-dap-python
tries to detect your project venv
and should recognize any
dependencies your project has. See Python dependencies and
virtualenv
- Implicit via uv
See Usage: You need to use require("dap-python").setup("uv")
To install the python tree-sitter parser you can either:
- Use
:TSInstall python
from nvim-treesitter - Compile the parser from tree-sitter-python and copy it into
.config/nvim/parser/
:git clone https://github.com/tree-sitter/tree-sitter-python.git
cd tree-sitter-python
cc -O2 -o ~/.config/nvim/parser/python}.so -I./src src/parser.c src/scanner.cc -shared -Os -lstdc++ -fPIC
-
Call
setup
in yourinit.lua
to register the adapter and configurations.If installed in a virtual environment:
require("dap-python").setup("/path/to/venv/bin/python") -- If using the above, then `/path/to/venv/bin/python -m debugpy --version` -- must work in the shell
If installed globally:
require("dap-python").setup("python3") -- If using the above, then `python3 -m debugpy --version` -- must work in the shell
Newer versions of
debugpy
also include adebugpy-adapter
executable which you can use in place of thepython
executable.If using uv:
require("dap-python").setup("uv")
-
Use
nvim-dap
as usual.- Call
:lua require('dap').continue()
to start debugging. - See
:help dap-mappings
and:help dap-api
. - Use
:lua require('dap-python').test_method()
to debug the closest method above the cursor.
Supported test frameworks are
unittest
,pytest
anddjango
. By default it tries to detect the runner by probing for presence ofpytest.ini
ormanage.py
, or for atool.pytest
directive insidepyproject.toml
, if none are present it defaults tounittest
.To configure a different runner, change the
test_runner
variable. For example, to configurepytest
set the test runner like this in yourinit.lua
:require('dap-python').test_runner = 'pytest'
You can also add custom runners. An example in
Lua
:local test_runners = require('dap-python').test_runners -- `test_runners` is a table. The keys are the runner names like `unittest` or `pytest`. -- The value is a function that takes two arguments: -- The classnames and a methodname -- The function must return a module name and the arguments passed to the module as list. ---@param classnames string[] ---@param methodname string? test_runners.your_runner = function(classnames, methodname) local path = table.concat({ table.concat(classnames, ":"), methodname, }, "::") return 'modulename', {"-s", path} end
- Call
See :help dap-python
nnoremap <silent> <leader>dn :lua require('dap-python').test_method()<CR>
nnoremap <silent> <leader>df :lua require('dap-python').test_class()<CR>
vnoremap <silent> <leader>ds <ESC>:lua require('dap-python').debug_selection()<CR>
If you call the require('dap-python').setup
method it will create a
few nvim-dap
configuration entries. These configurations are general
purpose configurations suitable for many use cases, but you may need to
add additional configurations or customize them.
To add additional configurations you can create per project
.vscode/launch.json
configuration files. See :help dap-launch.json
.
Or you can add your own global entries by extending the
dap.configurations.python
list after calling the setup
function:
require('dap-python').setup('debugpy-adapter') -- or uv, or path to python, see #usage
table.insert(require('dap').configurations.python, {
type = 'python',
request = 'launch',
name = 'My custom launch configuration',
-- `program` is what you'd use in `python <program>` in a shell
-- If you need to run the equivalent of `python -m <module>`, replace
-- `program = '${file}` entry with `module = "modulename"
program = '${file}',
console = "integratedTerminal",
-- Other options:
-- See https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings
})
The Debugpy Wiki contains a list of all supported configuration options.
nvim-dap-python
by default tries to detect a virtual environment and uses it
when debugging your application. It looks for:
- The environment variables
VIRTUAL_ENV
andCONDA_PREFIX
- The folders
venv
,.venv
,env
,.env
relative to either the current working directory or theroot_dir
of a active language server client. See:h lsp.txt
for more information about the latter.
If you're using another way to manage virtual environments, you can set a
custom resolve_python
function:
require('dap-python').resolve_python = function()
return '/absolute/path/to/python'
end
Or explicitly set the pythonPath
property within your debugpy/nvim-dap
configurations. See :h dap-configuration
and Launch/Attach
Settings
A test runner building upon vim-test with nvim-dap support. Aims to work for all python runners.
- Generate docs using vimcats:
vimcats -f -t lua/dap-python.lua > doc/dap-python.txt