Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mypy does not work under a venv #662

Open
rhusiev opened this issue Sep 20, 2024 · 7 comments
Open

mypy does not work under a venv #662

rhusiev opened this issue Sep 20, 2024 · 7 comments

Comments

@rhusiev
Copy link

rhusiev commented Sep 20, 2024

When I install mypy for my user (pip install --user mypy), it is recognized by nvim-lint and works.

However, when I use a custom environment for my linters (I create some python -m venv linters_venv, add it to bash, .profile and vim.env.PATH), nvim-lint no longer runs mypy.

I can run mypy in my terminal and using :!mypy in neovim, but nvim-lint does not seem to see it. I also tried changing the require('lint').linters.mypy.cmd to the absolute path to mypy, but nvim-lint still did not run it.

@mfussenegger
Copy link
Owner

If mypy is in $PATH nvim-lint should pick it up.

There's probably something else wrong. Maybe the --python-executable parameter doesn't match

Does it work if you source linters_venv/bin/active before starting nvim?

@rhusiev
Copy link
Author

rhusiev commented Oct 24, 2024

It does not work even with the environment sourced before starting neovim.

@hbibel
Copy link

hbibel commented Oct 28, 2024

@rhusiev Can you post your relevant config? I have set up my nvim to use mypy from a virtual environment and it works as expected.

This is essentially what I'm doing:

local nvim_lint = require("lint")

local venv_dir = "path/to/my/venv" -- computed during startup

nvim_lint.linters.mypy.cmd = venv_dir .. "/bin/mypy"
-- args copied from https://github.com/mfussenegger/nvim-lint/blob/master/lua/lint/linters/mypy.lua
nvim_lint.linters.mypy.args = {
  mypy_path,
  "--show-column-numbers",
  "--show-error-end",
  "--hide-error-context",
  "--no-color-output",
  "--no-error-summary",
  "--no-pretty",
  "--python-executable",
  venv_dir .. "/bin/python",
}

nvim_lint.linters_by_ft = {
  python = { "mypy" },
}

Note that I only do this because I'm too lazy to activate the environment. If you activate your environment setting nvim_lint.linters.mypy.cmd and nvim_lint.linters.mypy.args should not be required.

@rhusiev
Copy link
Author

rhusiev commented Oct 28, 2024

@hbibel Here you are:

local lint = require("lint")
local mypy = lint.linters.mypy
local mypy_path = vim.fn.expand("$HOME/.local/share/venvs/linters_venv/")
mypy.cmd = mypy_path .. "bin/mypy"
mypy.args = vim.list_extend(mypy.args, {
    function()
        local filename = vim.api.nvim_buf_get_name(0)
        local root_dir
        root_dir = lspconfig_util.find_git_ancestor(filename)
        root_dir = root_dir
            or lspconfig_util.root_pattern("setup.py", "pyproject.toml", "setup.cfg", "requirements.txt")(filename)
        root_dir = root_dir or lspconfig_util.root_pattern("*.py")(filename)
        local cache_dir = vim.fn.expand("$HOME/.cache/mypy/") .. root_dir
        return "--cache-dir=" .. cache_dir .. " --python-executable=" .. mypy_path .. "bin/python"
    end
})
...
lint.linters_by_ft = {
    python = { "flake8", "mypy" },
    ...
}

@hbibel
Copy link

hbibel commented Oct 28, 2024

@rhusiev can you make two changes:

  1. Don't extend the args with a function, but with values
  2. Don't concatenate args into a single string, --cache-dir=... and --python-executable=... should be separate entries in the table

Something like this:

    mypy.args = vim.list_extend(mypy.args, {
        "--cache-dir=" .. cache_dir,
        "--python-executable=" .. mypy_path .. "bin/python",
    })

Apart from that I think it should work. Also make sure you're not using a very old mypy version. Adding vim.print(mypy.args) should also help with debugging.

@rhusiev
Copy link
Author

rhusiev commented Nov 6, 2024

Even when I do it like this:

local mypy = lint.linters.mypy
local mypy_path = vim.fn.expand("$HOME/.local/share/venvs/linters_venv/")
mypy.cmd = mypy_path .. "bin/mypy"
mypy.args = {
	"--python-executable",
	mypy_path .. "bin/python",
	"--show-column-numbers",
	"--show-error-end",
	"--hide-error-codes",
	"--hide-error-context",
	"--no-color-output",
	"--no-error-summary",
	"--no-pretty",
}

Without extending mypy.args and a function, it still does not work.

@the-citto
Copy link

the-citto commented Nov 9, 2024

still a Lua noob here so thank you very much @hbibel's for the hint on how to amend mypy's args

same, I don't activate virtual environments, preferring to refer to the executables within

I'm always using pyproject.toml, and global mypy installed with my package manager

running mypy from command line, it was correctly picking up python_executable from pyproject.toml, but nvim.lint wasn't

I ended up removing all args, relying on pyproject.toml as the only source for my settings

local M = {
    "mfussenegger/nvim-lint",
    dependencies = {
        "williamboman/mason.nvim",
    },
}

M.config = function()
    local lint = require("lint")
    lint.linters.mypy.args = {}
    lint.linters_by_ft = {
        python = {
            "mypy",
        },
    }
    local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true })
    vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, {
        group = lint_augroup,
        callback = function()
            lint.try_lint()
        end,
    })
end

return M

I think some default setting are very good to have, even if not for me, but considering that, for mypy, --python-executable is optional, I think it could not be there at all?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants