mfussenegger / nvim-dap-python

An extension for nvim-dap, providing default configurations for python and methods to debug individual test methods or classes.
GNU General Public License v3.0
539 stars 48 forks source link

DAP `test_method` not uses `VIRTUAL_ENV` path #132

Closed victorfernandesraton closed 5 months ago

victorfernandesraton commented 6 months ago

Description

When i try to use test_method or test_class itś seens it not apply path verification, run in $HOME/.local/share/nvim/mason/packages/debugpy/venv/bin/python instead of select runtime from current virtualenv, but when i use continue, seens work fine

Steps to reproduce

I currently using :checkhealth and have this results above

Python 3 provider (optional) ~
- WARNING No Python executable found that can `import neovim`. Using the first available executable for diagnostics.
- WARNING Could not load Python 3:
  /home/v_raton/git/personal/vagabot/.venv/bin/python3 does not have the "neovim" module.
  python3.12 not found in search path or not executable.
  /home/v_raton/git/personal/vagabot/.venv/bin/python3.11 does not have the "neovim" module.
  python3.10 not found in search path or not executable.
  python3.9 not found in search path or not executable.
  python3.8 not found in search path or not executable.
  python3.7 not found in search path or not executable.
  /home/v_raton/git/personal/vagabot/.venv/bin/python does not have the "neovim" module.
  - ADVICE:
    - See :help |provider-python| for more information.
    - You may disable this provider (and warning) by adding `let g:loaded_python3_provider = 0` to your init.vim
- Executable: Not found

Also i use this config file

-- Debugging Support
return {
    -- https://github.com/rcarriga/nvim-dap-ui
    'rcarriga/nvim-dap-ui',
    event = 'VeryLazy',
    dependencies = {
        -- https://github.com/mfussenegger/nvim-dap
        'mfussenegger/nvim-dap',
        -- https://github.com/theHamsta/nvim-dap-virtual-text
        'theHamsta/nvim-dap-virtual-text',   -- inline variable text while debugging
        -- https://github.com/nvim-telescope/telescope-dap.nvim
        'nvim-telescope/telescope-dap.nvim', -- telescope integration with dap
        "jay-babu/mason-nvim-dap.nvim",
        'mfussenegger/nvim-dap-python',
    },
    opts = {
        controls = {
            element = "repl",
            enabled = false,
            icons = {
                disconnect = "",
                pause = "",
                play = "",
                run_last = "",
                step_back = "",
                step_into = "",
                step_out = "",
                step_over = "",
                terminate = ""
            }
        },
        element_mappings = {},
        expand_lines = true,
        floating = {
            border = "single",
            mappings = {
                close = { "q", "<Esc>" }
            }
        },
        force_buffers = true,
        icons = {
            collapsed = ">",
            current_frame = ">",
            expanded = ""
        },
        layouts = {
            {
                elements = {
                    {
                        id = "scopes",
                        size = 0.50
                    },
                    {
                        id = "stacks",
                        size = 0.50
                    },
                },
                size = 40,
                position = "left", -- Can be "left" or "right"
            },
            {
                elements = {
                    "repl",
                    "console",
                },
                size = 10,
                position = "bottom", -- Can be "bottom" or "top"
            }
        },
        mappings = {
            edit = "e",
            expand = { "<CR>", "<2-LeftMouse>" },
            open = "o",
            remove = "d",
            repl = "r",
            toggle = "t"
        },
        render = {
            indent = 1,
            max_value_lines = 100
        }
    },
    config = function(_, opts)
        local dap = require('dap')

        require('mason-nvim-dap').setup {
            -- Makes a best effort to setup the various debuggers with
            -- reasonable debug configurations
            automatic_setup = true,

            -- You can provide additional configuration to the handlers,
            -- see mason-nvim-dap README for more information
            handlers = {},

            -- You'll need to check that you have the required things installed
            -- online, please don't ask me how to install them :)
            ensure_installed = {
                -- Update this to ensure that you have the debuggers for the langs you want
                'python',
                'delve',
                'debupy'
            },
        }

        local keymap = vim.keymap
        -- dap keybinds
        keymap.set("n", "<leader>bb", function() dap.toggle_breakpoint() end, { desc = "DAP toggle breakpoint" })
        keymap.set("n", "<leader>bc", function() dap.set_breakpoint(vim.fn.input('Breakpoint condition: ')) end,
            { desc = "DAP set breakpoint" })
        keymap.set("n", "<leader>bl", function() dap.set_breakpoint(nil, nil, vim.fn.input('Log point message: ')) end)
        keymap.set("n", '<leader>br', function() dap.clear_breakpoints() end, { desc = "DAP clear all breakpoints" })
        keymap.set("n", "<F5>", function() dap.continue() end, { desc = "DAP continue" })
        keymap.set("n", "<leader>dpr", function() dap.test_method() end, { desc = "DAP run test for method" })
        keymap.set("n", '<leader>ba', '<cmd>Telescope dap list_breakpoints<cr>', { desc = "DAP list breakpoint" })
        keymap.set("n", "<leader>dj", function() dap.step_over() end, { desc = "DAP step over" })
        keymap.set("n", "<leader>dk", function() dap.step_into() end, { desc = "DAP step into" })
        keymap.set("n", "<leader>do", function() dap.step_out() end, { desc = "DAP step out" })
        keymap.set("n", '<leader>dd', function()
            require('dap').disconnect(); require('dapui').close();
        end, { desc = "DAP disconnect" })
        keymap.set("n", '<leader>dt', function()
            require('dap').terminate(); require('dapui').close();
        end, { desc = "DAP terminate" })
        keymap.set("n", "<leader>dr", function() dap.repl.toggle() end, { desc = "DAP REPL toggle" })
        keymap.set("n", "<leader>dl", function() dap.run_last() end, { desc = "DAP run last" })
        keymap.set("n", '<leader>di', function() require "dap.ui.widgets".hover() end, { desc = "DAP ui hoover" })
        keymap.set("n", '<leader>d?',
            function()
                local widgets = require "dap.ui.widgets"; widgets.centered_float(widgets.scopes)
            end)
        keymap.set("n", '<leader>df', '<cmd>Telescope dap frames<cr>')
        keymap.set("n", '<leader>dh', '<cmd>Telescope dap commands<cr>')
        keymap.set("n", '<leader>de', function() require('telescope.builtin').diagnostics({ default_text = ":E:" }) end)

        table.insert(require('dap').configurations.python, {
            type = 'python',
            request = 'launch',
            name = 'Run handler.py RPA',
            program = 'handler.py',
            console = "integratedTerminal",
        })

        vim.keymap.set("n", "<leader>dpt", ":lua require('dap-python').test_method()<CR>", { desc = "Test Method" })
        vim.keymap.set("n", "<leader>dpc", ":lua require('dap-python').test_class()<CR>", { desc = "Debug Class" })
        require('dapui').setup(opts)

        dap.listeners.after.event_initialized["dapui_config"] = function()
            require('dapui').open()
        end

        dap.listeners.before.event_terminated["dapui_config"] = function()
            -- Commented to prevent DAP UI from closing when unit tests finish
            -- require('dapui').close()
        end

        dap.listeners.before.event_exited["dapui_config"] = function()
            -- Commented to prevent DAP UI from closing when unit tests finish
            -- require('dapui').close()
        end
    end
}

And i have pytest.ini file, but when i run using test_method, i got this result

/home/v_raton/.local/share/nvim/mason/packages/debugp
y/venv/bin/python: No module named pytest

[Process exited 1]
mfussenegger commented 5 months ago

test_method goes through the same virtualenv detection as other configurations referring the debugpy adapter created by nvim-dap-python.

See https://github.com/mfussenegger/nvim-dap-python?tab=readme-ov-file#python-dependencies-and-virtualenv

victorfernandesraton commented 5 months ago

test_method goes through the same virtualenv detection as other configurations referring the debugpy adapter created by nvim-dap-python.

See https://github.com/mfussenegger/nvim-dap-python?tab=readme-ov-file#python-dependencies-and-virtualenv

But this behavior is not default when you append some configurations for create custon runs such as:


  table.insert(require('dap').configurations.python, {
      type = 'python',
      request = 'launch',
      name = 'Run handler.py RPA',
      program = 'handler.py',
      console = "integratedTerminal",
  })

I created a manual patch for this cases in my config for now in these functions above

local is_windows = function()
    return vim.fn.has("win32") == 1
end

local function python_exe(venv)
    if is_windows() then
        return venv .. '\\Scripts\\python.exe'
    end
    return venv .. '/bin/python'
end
local get_python_path = function()
    local venv_path = os.getenv('VIRTUAL_ENV')
    if venv_path then
        return python_exe(venv_path)
    end

    venv_path = os.getenv("CONDA_PREFIX")
    if venv_path then
        if is_windows() then
            return venv_path .. '\\python.exe'
        end
        return venv_path .. '/bin/python'
    end
end

And add as a pythonPath in custon configurations like

table.insert(dap.configurations.python, {
    type = 'python',
    request = 'launch',
    name = 'Run handler.py RPA',
    program = 'handler.py',
    console = "integratedTerminal",
    pythonPath = get_python_path()
})

I guess it's has something about sane default behavior here?