dense-analysis / ale

Check syntax in Vim/Neovim asynchronously and fix files, with Language Server Protocol (LSP) support
BSD 2-Clause "Simplified" License
13.48k stars 1.43k forks source link

Pylint running from wrong directory [Import Error] #3211

Open ginsburgnm opened 4 years ago

ginsburgnm commented 4 years ago

Information

VIM version

VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Mar 18 2020 18:29:15) Included patches: 1-1453

Operating System: Linux nginsburg-desktop 4.15.0-91-generic #92-Ubuntu SMP Fri Feb 28 11:09:48 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

What went wrong

As I filled out this bug report I kinda figured out what's wrong

Project structure

gitrepo/
    /main_file
    /{bunch of project metadata files}
    /lib
        /__init__.py
        /{a few module folders}
        /plugins <- this directory is in my git ignore
            /__init__.py
            /{a few git repos here} <- these directories are completely separate repos

Opening a file in the plugins directory results in an import error in ALE. Running pylint directly against that file does not result in any errors reported Opening a file with ALE disabled, and using syntastic instead results in no errors reported So there's some logical difference between the syntastic pylint linter and the ale pylint linter.

Opening a file outside of the plugins directory works as expected

I'm not good at vim scripts, so I'm not really sure exactly what's happening here or how to reasonably debug it. But it feels like pylint is being called from the wrong directory.

So I tried setting let g:ale_python_pylint_change_directory = 1 explicitly but there was no difference (which I guess is expected)

I then set it to 0 and it no longer reports the import error, what appears to be happening is that the pylint change directory is assuming the incorrect project root.

I think this is actually a bug because in your help

this is necessary for pylint to use a project pylintrc file, if present.

This suggests ale cannot utilize the projects pylintrc file.

Also, both pylint and syntastic are able to determine the correct output for these files.

Are you having trouble configuring ALE? Try asking for help on Stack Exchange or perhaps on Reddit instead. The GitHub issue tracker should be used for reporting bugs or asking for new features.

Reproducing the bug

  1. I embeded git repos
  2. Then got misreported pylint errors

:ALEInfo

Called vim libcopacetic/plugins/fleet/models/__init__.py from vim called ALEInfo Got this: From the output it does look like Ale is calling pylint from the wrong directory.

 Current Filetype: python
Available Linters: ['bandit', 'flake8', 'mypy', 'prospector', 'pycodestyle', 'pydocstyle', 'pyflakes', 'pyl
ama', 'pylint', 'pyls', 'pyre', 'vulture']
  Enabled Linters: ['pylint']
 Suggested Fixers:
  'add_blank_lines_for_python_control_statements' - Add blank lines before control statements.
  'autopep8' - Fix PEP8 issues with autopep8.
  'black' - Fix PEP8 issues with black.
  'isort' - Sort Python imports with isort.
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'reorder-python-imports' - Sort Python imports with reorder-python-imports.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
  'yapf' - Fix Python files with yapf.
 Linter Variables:
let g:ale_python_auto_pipenv = 0
let g:ale_python_pylint_auto_pipenv = 0
let g:ale_python_pylint_change_directory = 1
let g:ale_python_pylint_executable = 'pylint'
let g:ale_python_pylint_options = ''
let g:ale_python_pylint_use_global = 0
let g:ale_python_pylint_use_msg_id = 0
 Global Variables:
let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {'vim': ['vint'], 'go': ['golint'], 'puppet': ['puppet-lint'], 'json': ['jq'], 'ansible
': ['ansible-lint'], 'yaml': ['yamllint'], 'bash': ['shellcheck'], 'python': ['pylint']}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 1
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_info = '--'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
let g:ale_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
  Command History:
(executable check - success) /home/n0g/git/copacetic/venv/bin/pylint
(finished - exit code 2) ['/bin/bash', '-c', 'cd ''/home/n0g/git/copacetic/libcopacetic/plugins/fleet'' && ''/home/n0g/git/copacetic/venv/bin/pylint''  --output-format text --msg-template="{path}:{line}:{column}:
{msg_id} ({symbol}) {msg}" --reports n ''/home/n0g/git/copacetic/libcopacetic/plugins/fleet/models/__init__.py''']
<<<OUTPUT STARTS>>>
************* Module models
models/__init__.py:1:0: E0401 (import-error) Unable to import 'models.host'
models/__init__.py:2:0: E0401 (import-error) Unable to import 'models.interface'
----------------------------------------------------------------------
Your code has been rated at -40.00/10 (previous run: -40.00/10, +0.00)
<<<OUTPUT ENDS>>>
kevinoid commented 4 years ago

As you discovered, by default ALE runs pylint from the project root directory. From your log, it appears that ALE determined the project root to be /home/n0g/git/copacetic/libcopacetic/plugins/fleet and running pylint in that directory produces import errors. Is that correct?

What do you think ALE should do differently?

hsanson commented 4 years ago

@ginsburgnm as @kevinoid has said this is most likely a problem with the structure of your project that makes it difficult for ALE to determine the correct root directory. You can check what root path ALE is configuring by opening a file in the project and running this command:

:echo ale#python#FindProjectRoot("")  

If the output is not the correct root path for your project you can try overriding it by setting the g:ale_lsp_root variable:

let g:ale_lsp_root = {
  \ 'python': '/path/to/project/root'
  \}

Note that above will set that root path as the project root of every python project you work on. Instead you can either use buffer variables instead b:ale_lsp_root or set a function that determines and properly sets the root path for that particular project.

ginsburgnm commented 4 years ago

@kevinoid @hsanson So, I open up vim and run

echo ale#python#FindProjectRoot("") 

on the __init__.py file in the fleet directory and I get the appropriate project root /home/n0g/git/copacetic/ in the same vim instance, if I open up any other file in the fleet directory, that file assumes the project root is /home/n0g/git/copacetic/libcopacetic/plugins/fleet

So same vim instance, same directory, different results. That''s likely some wonky python thing because I opened the __init__.py.

My error reporting is resolved by telling ALE to not change directory.

The piece that I believe to be a bug is: ALE should be able to utilize a project's pylintrc file if you disable changing directory. Just look at the current working directory that vim was opened in. Your help at least suggests that this is not the cas.

It's not a huge deal for me, as all of my projects currently use the same rc file so defaulting back to my global rc file is fine; but I can foresee a situation where someone has multiple rc files for different python projects.