null-ls.nvim
null-ls.nvim copied to clipboard
MyPy Diagnostics not showing
FAQ
- [X] I have checked the FAQ and it didn't resolve my problem.
Issues
- [X] I have checked existing issues and there are no issues with the same problem.
Neovim Version
NVIM v0.8.0-1210-gd367ed9b2
Dev Version?
- [X] I am using a stable Neovim release version, or if I am using a dev version of Neovim I have confirmed that my issue is reproducible on a stable version.
Operating System
Linux version 5.15.68.1-microsoft-standard-WSL2 (oe-user@oe-host) (x86_64-msft-linux-gcc (G CC) 9.3.0, GNU ld (GNU Binutils) 2.34.0.20200220) #1 SMP Mon Sep 19 19:14:52 UTC 2022
Minimal Config
-- this template is borrowed from nvim-lspconfig
local on_windows = vim.loop.os_uname().version:match("Windows")
local function join_paths(...)
local path_sep = on_windows and "\\" or "/"
local result = table.concat({ ... }, path_sep)
return result
end
vim.g.loaded_remote_plugins = ""
vim.cmd([[set runtimepath=$VIMRUNTIME]])
local temp_dir = vim.loop.os_getenv("TEMP") or "/tmp"
vim.cmd("set packpath=" .. join_paths(temp_dir, "nvim", "site"))
local package_root = join_paths(temp_dir, "nvim", "site", "pack")
local install_path = join_paths(package_root, "packer", "start", "packer.nvim")
local compile_path = join_paths(install_path, "plugin", "packer_compiled.lua")
local null_ls_config = function()
local null_ls = require("null-ls")
-- add only what you need to reproduce your issue
null_ls.setup({
sources = {
null_ls.builtins.diagnostics.mypy,
null_ls.builtins.diagnostics.flake8,
},
debug = true,
})
end
local function load_plugins()
-- only add other plugins if they are necessary to reproduce the issue
require("packer").startup({
{
"wbthomason/packer.nvim",
{
"jose-elias-alvarez/null-ls.nvim",
requires = { "nvim-lua/plenary.nvim" },
config = null_ls_config,
},
},
config = {
package_root = package_root,
compile_path = compile_path,
},
})
end
if vim.fn.isdirectory(install_path) == 0 then
vim.fn.system({ "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path })
end
load_plugins()
require("packer").sync()
Steps to Reproduce
Requires:
- python
- flake8
- mypy
import math
import collections
def print_list(a: list) -> None:
print(a)
print_list(1) # expect mypy diagnostic here
print_list([1, 2, 3])
vim --clean -u minimal_init.lua temp.py
Reproducibility Check
- [X] I confirm that my minimal config is based on the
minimal_init.luatemplate and that my issue is reproducible by runningnvim --clean -u minimal_init.luaand following the steps above.
Expected Behavior
Diagnostics from mypy to be both displayed in buffer and in location list with lua vim.diagnostic.setloclist().
Actual Behavior
Diagnostics are observed for flake 8 but not mypy. Null-ls logs show that both tools run and report diagnostic issues.

Ref: https://github.com/jose-elias-alvarez/null-ls.nvim/discussions/957
Debug Log
...
[TRACE Sun Oct 23 18:12:50 2022] ...t/null-ls.nvim/lua/null-ls/helpers/generator_factory.lua:204: output: nil
[TRACE Sun Oct 23 18:12:50 2022] ...ck/packer/start/null-ls.nvim/lua/null-ls/diagnostics.lua:181: received diagnostics from source 2
[TRACE Sun Oct 23 18:12:50 2022] ...ck/packer/start/null-ls.nvim/lua/null-ls/diagnostics.lua:182: { {
code = "F401",
col = 0,
end_col = 11,
end_lnum = 0,
lnum = 0,
message = "'math' imported but unused",
row = "1",
severity = 3,
source = "flake8"
}, {
code = "F401",
col = 0,
end_col = 18,
end_lnum = 1,
lnum = 1,
message = "'collections' imported but unused",
row = "2",
severity = 3,
source = "flake8"
}, {
code = "E302",
col = 0,
end_col = 1,
end_lnum = 3,
lnum = 3,
message = "expected 2 blank lines, found 1",
row = "4",
severity = 1,
source = "flake8"
} }
[TRACE Sun Oct 23 18:12:50 2022] ...t/null-ls.nvim/lua/null-ls/helpers/generator_factory.lua:203: error output: nil
[TRACE Sun Oct 23 18:12:50 2022] ...t/null-ls.nvim/lua/null-ls/helpers/generator_factory.lua:204: output: typing/temp.py:8:12: error: Argument 1 to "print_list" has incompatible type "int"; expected "List[Any]" [arg-type]
[TRACE Sun Oct 23 18:12:50 2022] ...ck/packer/start/null-ls.nvim/lua/null-ls/diagnostics.lua:181: received diagnostics from source 1
[TRACE Sun Oct 23 18:12:50 2022] ...ck/packer/start/null-ls.nvim/lua/null-ls/diagnostics.lua:182: { {
bufnr = 3,
code = "arg-type",
col = 11,
end_col = 0,
end_lnum = 8,
filename = "typing/temp.py",
lnum = 7,
message = 'Argument 1 to "print_list" has incompatible type "int"; expected "List[Any]"',
row = "8",
severity = 1,
source = "mypy"
} }
Help
No
Implementation Help
No response
Requirements
- [X] I have read and followed the instructions above and understand that my issue will be closed if I did not provide the required information.
I'm having the same issue. I tried to set the method to DIAGNOSTICS_ON_SAVE, but no dice. However, it's saying in my logs sometimes:
[TRACE Sun Oct 30 09:54:17 2022] .../site/pack/packer/start/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method textDocument/didSave
[TRACE Sun Oct 30 09:54:17 2022] ...ack/packer/start/null-ls.nvim/lua/null-ls/generators.lua:21: running generators for method NULL_LS_DIAGNOSTICS_ON_SAVE
[DEBUG Sun Oct 30 09:54:17 2022] ...ack/packer/start/null-ls.nvim/lua/null-ls/generators.lua:24: no generators available
Other times, I see the full diagnostics in the log
One issue I have that is exclusive to mypy is that if a) the file was just created, the generator complains and mypy stops working for the nvim session b) It seems to only work when the file is in the path under the starting directory of nvim.
Thanks for putting this together. On my end, I see the mypy diagnostic as well, and everything updates correctly on change:
I wonder if this is related to some kind of project-/environment-local configuration. Have you tried it in a random (i.e. non-project) directory?
One issue I have that is exclusive to mypy is that if a) the file was just created, the generator complains and mypy stops working for the nvim session b) It seems to only work when the file is in the path under the starting directory of nvim.
I don't know if either is related to the parent issue, but a) seems related to python/mypy#4746. b) should have been fixed by 17e81c1c1f21f8f6d11a4141a490a0b37974a52b, but if it's still an issue after updating, please open another issue.
Thank you!. Will update and report If I still see something strange.
I've been having a similar problem and I was able to fix it by commenting out multiple_files = true in lua/null-ls/builtins/diagnostics/mypy.lua. Not sure why that works, though.
@danielroseman not sure why there would be multiple_files enabled for mypy, it works perfectly fine on single files? But if you do enable it the filename needs to be right. I guess ideally be having absolute paths in the diagnostics the the built-in produces.
I also have a similar problem. I installed mypy globally and tried to edit files with venv activated. Mypy works again after I installed mypy into the venv. Flake8 is also installed globally but it works just fine.
EDIT: Not really solved. The diagnostics are gone after switching buffer. I will add more details after figuring this out.
I faced a similar problem when editing files that were not saved yet
It seems to me that this may be related to using --shadow-file file when invoking mypy. Here is the original code:
args = function(params)
return {
"--hide-error-codes",
"--hide-error-context",
"--no-color-output",
"--show-column-numbers",
"--show-error-codes",
"--no-error-summary",
"--no-pretty",
"--shadow-file",
params.bufname,
params.temp_path,
params.bufname,
}
end,
So null-ls passes both path to the current buffer and temp_path to mypy. In my case the first do not exist yet, that's why mypy crashes. I am not sure that --shadow-file should be used here at all. Maybe I miss something, but I believe that passing temp_path should be enough for it to work correctly.
I changed the code to:
args = function(params)
return {
"--hide-error-context",
"--no-color-output",
"--show-column-numbers",
"--show-error-codes",
"--no-error-summary",
"--no-pretty",
params.temp_path,
}
end,
And now it works perfectly
UPDATE: I'm actually wrong, it doesn't. Using --shadow-file is necessary in order for mypy to respect local configuration (e.g. pyproject.toml), otherwise it runs with general settings. I wonder if there is another way to solve this
Had the same issue. I realized by looking at the logs that the buffer numbers were wrong, not matching the actual buffer where the files were. The issue for me was that my mypy.ini is not in the project root. By default, null-ls finds the directory where the mypy.ini is and selects it as the root for spawning black command (https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/lua/null-ls/builtins/diagnostics/mypy.lua#L67), which led to paths missing that first directory and not matching with the actual file path.
Luckily every setting can be overridden.
I fixed it by hardcoding the root directory as cwd.
null_ls.builtins.diagnostics.mypy.with({
extra_args = { "--config-file", "backend/mypy.ini" },
cwd = function (_) return vim.fn.getcwd() end
}),
Hope this helps.
Is there any way to disable mypy for newly opened files which are not saved on disk yet?
Is there any way to disable mypy for newly opened files which are not saved on disk yet?
I think this is related to https://github.com/python/mypy/issues/4746. You might be able to work around it using something like this (untested):
local utils = require("null-ls.utils")
local mypy = null_ls.builtins.diagnostics.mypy.with({
runtime_condition = function(params)
return utils.path.exists(params.bufname)
end,
})
But I think this is fundamentally an issue that should be solved upstream.
@jose-elias-alvarez Thank you, it works!
Great workaround. IMO should be default for mypy since pretty much everybody is going to be hitting this when creating a new .py file.
Happy to review any PRs that improve on any of the issues described here. I'm not a mypy user, and the ecosystem is complicated enough that I would want any potential solutions to be tested by actual users.
Another failure mode for mypy is when one uses the lsp go to definition of a site packages library function. In that case mypy will fail trying to analyze the new file complaining about user types mypy_extenstions and typing_extensions being shadowed (this is simply a mypy limitation). Then null-ls will mark the generator as failed and not run it again for the rest of the neovim session.