I use ALE to run linters while editing Python code in vim. When working on code in a package, I can't get ALE to respect the pylint configuration in the project root. I've had it in .pylintrc
as well as in pyproject.toml
, both in the root directory of the project. Digging in a bit more, I find this is because ALE isn't correctly identifying the root directory of the project. I think this is because ALE uses vim's alternate file rather than the current file in finding the project root. (i.e., #
rather than %
.)
Actual behavior: In terms of the package structure described below, I use vim to open config.py
, which contains this line: from . import error as err
. ALE's pylint flags it as a "relative-beyond-top-level", which it's not - the package works fine with the Python interpreter. Using :ALEInfo
shows me that pylint was run from top/src/package/
rather than top/
. No custom ~/.vimrc
is installed.
Expected behavior: ALE runs pylint from the correct directory and this line is not flagged as an error.
My question: Is this an ALE bug or am I using it wrong? I don't understand why you would use the alternate file rather than the current file in finding the project root.
Here's the project structure:
top/
[config files including setup.py, setup.cfg, pyproject.toml]
[other directories]
src/
__init__.py
package/
__init__.py
config.py
error.py
[other files]
Complete :ALEInfo
output:
Current Filetype: python
Available Linters: ['flake8', 'mypy', 'prospector', 'pycodestyle', 'pyflakes', 'pylint', 'pyls', 'pyre', 'vulture']
Enabled Linters: ['flake8', 'mypy', '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.
'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_flake8_change_directory = 1
let g:ale_python_flake8_executable = 'flake8'
let g:ale_python_flake8_options = ''
let g:ale_python_flake8_use_global = 0
let g:ale_python_mypy_executable = 'mypy'
let g:ale_python_mypy_ignore_invalid_syntax = 0
let g:ale_python_mypy_options = ''
let g:ale_python_mypy_use_global = 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
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_save = 1
let g:ale_lint_on_text_changed = 'always'
let g:ale_lint_on_insert_leave = 0
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = 0
let g:ale_list_window_size = 10
let g:ale_list_vertical = 0
let g:ale_loclist_msg_format = '%code: %%s'
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 = 0
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_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
Command History:
(executable check - failure) flake8
(executable check - failure) mypy
(executable check - success) /Users/will/github/top/env/bin/pylint
(finished - exit code 2) ['/opt/homebrew/bin/bash', '-c', 'cd ''/Users/will/github/top/src/package'' && ''/Users/will/github/top/env/bin/pylint'' --output-format text --msg-
template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n ''/Users/will/github/top/src/package/config.py''']
<<<OUTPUT STARTS>>>
[various style complaints omitted]
#
together witha:buffer
which is a buffer number passed as an argument, so you can see that:echo expand('#1:p:h')
will show the directory of file opened as buffer 1. You can see buffer numbers from output of:ls
or:buffers
commands... (Sorry, haven't had the time yet to think of why you might be having trouble with your issue specifically.):echo ale#python#FindProjectRootIni(bufnr())
and/or:echo ale#python#FindProjectRoot(bufnr())
, etc. to see what ALE thinks is the Python project root is, maybe that would help you troubleshoot the issue a little further?