null-ls.nvim icon indicating copy to clipboard operation
null-ls.nvim copied to clipboard

MyPy Diagnostics not showing

Open tlelson opened this issue 3 years ago • 16 comments

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.lua template and that my issue is reproducible by running nvim --clean -u minimal_init.lua and 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.

197379305-fe38f389-310e-4a9d-9f76-31cc81eec758

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.

tlelson avatar Oct 23 '22 21:10 tlelson

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

sirupsen avatar Oct 30 '22 14:10 sirupsen

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.

rsdenijs avatar Oct 31 '22 09:10 rsdenijs

Thanks for putting this together. On my end, I see the mypy diagnostic as well, and everything updates correctly on change:

Screenshot 2022-11-03 at 10 56 16 AM

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?

jose-elias-alvarez avatar Nov 03 '22 15:11 jose-elias-alvarez

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.

jose-elias-alvarez avatar Nov 03 '22 15:11 jose-elias-alvarez

Thank you!. Will update and report If I still see something strange.

rsdenijs avatar Nov 06 '22 20:11 rsdenijs

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 avatar Nov 24 '22 15:11 danielroseman

@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.

sblask avatar Nov 24 '22 19:11 sblask

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.

AllanChain avatar Dec 02 '22 11:12 AllanChain

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

olzhasar avatar Dec 08 '22 16:12 olzhasar

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.

s-kovacevic avatar Dec 08 '22 23:12 s-kovacevic

Is there any way to disable mypy for newly opened files which are not saved on disk yet?

olzhasar avatar Dec 09 '22 11:12 olzhasar

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 avatar Dec 10 '22 18:12 jose-elias-alvarez

@jose-elias-alvarez Thank you, it works!

olzhasar avatar Dec 11 '22 18:12 olzhasar

Great workaround. IMO should be default for mypy since pretty much everybody is going to be hitting this when creating a new .py file.

rsdenijs avatar Dec 14 '22 13:12 rsdenijs

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.

jose-elias-alvarez avatar Dec 14 '22 20:12 jose-elias-alvarez

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.

rsdenijs avatar Jan 22 '23 09:01 rsdenijs