Mypy sends a warning notification when opening a new Python file
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
v0.9.5
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
macOS Sonoma 14.4
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,
},
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",
{
"nvimtools/none-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 })
load_plugins()
require("packer").sync()
else
load_plugins()
require("packer").sync()
end
Steps to Reproduce
- Install Mypy on your system.
-
nvim --clean -u minimal_init.lua - Open a new Python file:
:e bar.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
No warning is displayed.
Actual Behavior
A warning message gets displayed:
[null-ls] failed to run generator: ...m/lazy/none-ls/lua/null-ls/helpers/generator_factory.lua:228: error in generator output: mypy: can't read file '/Users/grzesiek/bar.py': No such file or directory
Debug Log
[TRACE Sat Mar 16 09:43:04 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/rpc.lua:106: received LSP request for method shutdown
[TRACE Sat Mar 16 09:43:04 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/rpc.lua:131: received LSP notification for method exit
[TRACE Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/client.lua:114: starting null-ls client
[TRACE Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/rpc.lua:106: received LSP request for method initialize
[TRACE Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/rpc.lua:131: received LSP notification for method initialized
[TRACE Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/rpc.lua:131: received LSP notification for method textDocument/didOpen
[TRACE Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/generators.lua:21: running generators for method NULL_LS_DIAGNOSTICS_ON_OPEN
[DEBUG Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/helpers/generator_factory.lua:329: spawning command "mypy" at /Users/grzesiek/sandbox with args { "--hide-error-codes", "--hide-error-context", "--no-color-output", "--show-absolute-path", "--show-column-numbers", "--show-error-codes", "--no-error-summary", "--no-pretty", "--shadow-file", "/Users/grzesiek/sandbox/bar.py", "/Users/grzesiek/sandbox/.null-ls_814785_bar.py", "/Users/grzesiek/sandbox/bar.py" }
[TRACE Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/helpers/generator_factory.lua:207: error output: mypy: can't read file '/Users/grzesiek/sandbox/bar.py': No such file or directory
[TRACE Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/helpers/generator_factory.lua:208: output: nil
[WARN Sat Mar 16 09:43:08 2024] /tmp/nvim/site/pack/packer/start/none-ls.nvim/lua/null-ls/generators.lua:94: failed to run generator: ...t/none-ls.nvim/lua/null-ls/helpers/generator_factory.lua:228: error in generator output: mypy: can't read file '/Users/grzesiek/sandbox/bar.py': No such file or directory
Help
Yes
Implementation Help
Hints for how to change the default Mypy config to work with buffers not backed by files.
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.
duplicate of #66
This is not a duplicate. #66 is about a failure by none-ls to create a temporary in a nonexistent path. This issue is about Mypy’s configuration being setup in such a way that none-ls sends a non-existent file name to Mypy. These two issues have most likely different causes.
Ah, my bad. Sorry for that.
I have the same problem in my windows installation of neovim. I thought this could be a problem with mypy, and cheched the source code for the mypy.lua file in diagnostics (https://github.com/nvimtools/none-ls.nvim/blob/main/lua/null-ls/builtins/diagnostics/mypy.lua). the default "args" option for mypy is the following function:
args = function(params)
return {
"--hide-error-codes",
"--hide-error-context",
"--no-color-output",
"--show-absolute-path",
"--show-column-numbers",
"--show-error-codes",
"--no-error-summary",
"--no-pretty",
"--shadow-file",
params.bufname,
params.temp_path,
params.bufname,
}
end,
I think the last flag, --shadow-file, is causing the problem.
--shadow-file has the following structure in mypy: --shadow-file SOURCE_FILE SHADOW_FILE
It is supposed to make mypy typecheck the SHADOW_FILE, while diagnostics still refer to SOURCE_FILE. However, in the repository of mypy there is a bug report open (https://github.com/python/mypy/issues/4746), that shows mypy complaining if the SOURCE_FILE doesn't exist when using --shadow-file.
the report uses the following example:
mypy --shadow-file error.py shadow.py error.py
mypy: can't read file 'error.py': No such file or directory
and the structure of the default args in mypy.lua is equivalent to:
mypy <other flags>... --shadow-file bufname, temp_path, bufname
mypy complains that bufname does not exist, given that neovim opens a new buffer without saving by default, the same way it happens in the report. It is a issue with mypy and not null-ls/none-ls.
removing the --shadow-file flag, and changing the positional args to only params.temp_path, solves the issue.
- with the default args function:
local null_ls = require("null-ls")
local opts = {
sources = {
null_ls.builtins.diagnostics.mypy,
}
}
return opts
the error happens:
and mypy isn't active:
- Changing the defaults:
local null_ls = require("null-ls")
local opts = {
sources = {
null_ls.builtins.diagnostics.mypy.with({
args = function (params)
return {
"--hide-error-codes",
"--hide-error-context",
"--no-color-output",
"--show-absolute-path",
"--show-column-numbers",
"--show-error-codes",
"--no-error-summary",
"--no-pretty",
params.temp_path,
}
end
}),
}
}
return opts
the error is gone, and mypy is active:
The solution above partially worked for me. I still had to modify the diagnostic message to make sure it got linked to the correct buffer.
The cleanest solution as it would ideally be handled by the builtin internals.
null_ls.builtins.diagnostics.mypy.with({
-- see issue https://github.com/nvimtools/none-ls.nvim/issues/97
args = function (params)
return {
"--hide-error-codes",
"--hide-error-context",
"--no-color-output",
"--show-absolute-path",
"--show-column-numbers",
"--show-error-codes",
"--no-error-summary",
"--no-pretty",
params.temp_path,
}
end,
on_output = function(line, params)
line = line:gsub(params.temp_path:gsub("([^%w])", "%%%1"), params.bufname)
return null_ls.builtins.diagnostics.mypy._opts.on_output(line, params)
end,
}),
I was getting Source file found twice under different module names: "codehighlighter." and "codehighlighter" in my project from gzagatti’s solution, so I modified the fix even further to only eschew the shadow file parameter on non-existent files:
null_ls.builtins.diagnostics.mypy.with({
args = function(params)
local args = {
"--hide-error-codes",
"--hide-error-context",
"--no-color-output",
"--show-absolute-path",
"--show-column-numbers",
"--show-error-codes",
"--no-error-summary",
"--no-pretty",
}
local _, _, stat_err_name = vim.uv.fs_stat(params.bufname)
if stat_err_name == "ENOENT" then
return vim.list_extend(args, { params.temp_path })
else
return vim.list_extend(args, {
"--shadow-file",
params.bufname,
params.temp_path,
params.bufname,
})
end
end,
on_output = function(line, params)
line = line:gsub(params.temp_path:gsub("([^%w])", "%%%1"), params.bufname)
return null_ls.builtins.diagnostics.mypy._opts.on_output(line, params)
end,
})
I’ve run it once and it seems to work fine.