🪲 Python Debugging
Learn how to set up Python debugging in Neovim that works with venv-selector's virtual environment switching.
🚀 Quick Overview
When you switch virtual environments with venv-selector, your debugging setup should automatically use the correct Python interpreter and installed packages.
If mfussenegger/nvim-dap
and mfussenegger/nvim-dap-python
are installed, venv-selector automatically updates nvim-dap with the new Python path every time you switch virtual environments.
🎯 🛠️ nvim-dap Setup
Prerequisites
📦 Required Plugins
Install these plugins using your preferred plugin manager:
-- Using lazy.nvim
{
"mfussenegger/nvim-dap",
dependencies = {
"mfussenegger/nvim-dap-python",
},
}
-- Using packer.nvim
use {
"mfussenegger/nvim-dap",
requires = {
"mfussenegger/nvim-dap-python",
},
}
🐍 Install debugpy
You need debugpy
installed in each virtual environment you want to debug:
# In your virtual environment
pip install debugpy
debugpy must be installed in the virtual environment you're debugging. When you switch environments with venv-selector, make sure debugpy is available in the new environment.
You can also install debugpy globally or in a dedicated debug environment:
# Create dedicated debug environment
python -m venv ~/.virtualenvs/debugpy
source ~/.virtualenvs/debugpy/bin/activate
pip install debugpy
Basic Configuration
⚙️ nvim-dap-python Setup
Add this to your Neovim configuration:
-- Basic setup
require('dap-python').setup('python') -- Uses the python in PATH
-- OR: Use a dedicated debugpy environment
require('dap-python').setup('~/.virtualenvs/debugpy/bin/python')
How venv-selector integration works:
- When you switch virtual environments, venv-selector automatically updates nvim-dap
- The Python path in your debugging configurations gets updated
- Your breakpoints and debug sessions use the correct interpreter
🎮 Keybindings
Set up keybindings for debugging:
-- Debugging keybindings
vim.keymap.set('n', '<Leader>db', function() require('dap').toggle_breakpoint() end, { desc = "Toggle Breakpoint" })
vim.keymap.set('n', '<Leader>dc', function() require('dap').continue() end, { desc = "Continue" })
vim.keymap.set('n', '<Leader>do', function() require('dap').step_over() end, { desc = "Step Over" })
vim.keymap.set('n', '<Leader>di', function() require('dap').step_into() end, { desc = "Step Into" })
vim.keymap.set('n', '<Leader>dr', function() require('dap').repl.open() end, { desc = "Open REPL" })
-- Python-specific
vim.keymap.set('n', '<Leader>dpr', function() require('dap-python').test_method() end, { desc = "Test Method" })
vim.keymap.set('n', '<Leader>dpc', function() require('dap-python').test_class() end, { desc = "Test Class" })
Usage
- Set breakpoints by placing your cursor on a line and pressing
<Leader>db
- Start debugging by pressing
<Leader>dc
- Step through code using
<Leader>do
(over) or<Leader>di
(into) - Inspect variables in the REPL with
<Leader>dr
🔧 Troubleshooting
❌ Common Issues and Solutions
Issue: "No module named 'debugpy'"
Solution: Install debugpy in the active virtual environment:
pip install debugpy
Issue: Breakpoints not working
Causes and solutions:
- Wrong Python interpreter: Verify with
:lua print(require("venv-selector").python())
- debugpy not in venv: Install debugpy in the current virtual environment
- Path issues: Use absolute paths in debug configurations
Issue: Environment variables not available
Solution: Ensure venv-selector has activated the environment:
-- Check current environment
:lua print(require("venv-selector").venv())
🔍 Debug Information Commands
Use these commands to troubleshoot debugging issues:
-- Check current Python interpreter
:lua print(require("venv-selector").python())
-- Check virtual environment path
:lua print(require("venv-selector").venv())
-- Check DAP configurations
:lua print(vim.inspect(require('dap').configurations.python))
-- Open DAP REPL for interactive debugging
:lua require('dap').repl.open()
🚀 Advanced Configuration
Automatic Virtual Environment Detection
⚡ Auto-configure debugpy Path
Automatically use the correct Python interpreter for debugging:
-- Auto-setup function
local function setup_python_dap()
local python = require("venv-selector").python()
if python then
require('dap-python').setup(python)
end
end
-- Setup after venv selection
vim.api.nvim_create_autocmd("User", {
pattern = "VenvSelectPost", -- If this event exists
callback = setup_python_dap,
})
-- Or call it manually after switching environments
vim.keymap.set('n', '<Leader>ds', setup_python_dap, { desc = "Setup Python DAP" })
Custom Debug Configurations
🎛️ Advanced DAP Configurations
Add custom debug configurations for different scenarios:
require('dap').configurations.python = {
{
type = 'python',
request = 'launch',
name = 'Launch current file',
program = '${file}',
pythonPath = function()
return require("venv-selector").python() or 'python'
end,
},
{
type = 'python',
request = 'launch',
name = 'Launch with arguments',
program = '${file}',
args = function()
local args_string = vim.fn.input('Arguments: ')
return vim.split(args_string, " ", true)
end,
pythonPath = function()
return require("venv-selector").python() or 'python'
end,
},
{
type = 'python',
request = 'launch',
name = 'Run pytest',
module = 'pytest',
args = {'${file}'},
pythonPath = function()
return require("venv-selector").python() or 'python'
end,
},
}
📚 Additional Resources
- nvim-dap documentation:
:help dap
- nvim-dap-python repository: GitHub
- debugpy documentation: Microsoft debugpy
- Debug Adapter Protocol: Official spec
- Install
debugpy
in your virtual environments - Use the automatic Python path detection for seamless venv switching
- Set up keybindings that work with your workflow
- Test your debug setup with a simple script before complex projects
When you switch virtual environments with :VenvSelect
, your debugging automatically uses the correct Python interpreter and has access to all packages in that environment.