summaryrefslogtreecommitdiff
path: root/ale_linters
diff options
context:
space:
mode:
authorDiep Pham <mrfavadi@gmail.com>2022-04-24 06:28:33 +0700
committerGitHub <noreply@github.com>2022-04-24 08:28:33 +0900
commit6c51bb1573f0bf5deff04508769208fd503b5ff7 (patch)
treea7f223301a40cdcfc430c4ba9487742013df8581 /ale_linters
parente2ef4d91ee88c49fbc5aa3ec9b670acb1d24b81f (diff)
downloadale-6c51bb1573f0bf5deff04508769208fd503b5ff7.zip
Improve pylama linter output handling (#4106)
* Use JSON format for newer pylama version https://github.com/klen/pylama/blob/develop/Changelog The --format json option is added in pylama version 8.1.4. * Fix linting warnings for pylama
Diffstat (limited to 'ale_linters')
-rw-r--r--ale_linters/python/pylama.vim85
1 files changed, 70 insertions, 15 deletions
diff --git a/ale_linters/python/pylama.vim b/ale_linters/python/pylama.vim
index 73b59b07..14f8071a 100644
--- a/ale_linters/python/pylama.vim
+++ b/ale_linters/python/pylama.vim
@@ -22,6 +22,22 @@ function! ale_linters#python#pylama#GetExecutable(buffer) abort
return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama'])
endfunction
+function! ale_linters#python#pylama#RunWithVersionCheck(buffer) abort
+ let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer)
+ let l:exec_args = l:executable =~? 'pipenv\|poetry$'
+ \ ? ' run pylama'
+ \ : ''
+
+ let l:command = ale#Escape(l:executable) . l:exec_args . ' --version'
+
+ return ale#semver#RunWithVersionCheck(
+ \ a:buffer,
+ \ l:executable,
+ \ l:command,
+ \ function('ale_linters#python#pylama#GetCommand'),
+ \)
+endfunction
+
function! ale_linters#python#pylama#GetCwd(buffer) abort
if ale#Var(a:buffer, 'python_pylama_change_directory')
" Pylama loads its configuration from the current directory only, and
@@ -35,27 +51,33 @@ function! ale_linters#python#pylama#GetCwd(buffer) abort
return ''
endfunction
-function! ale_linters#python#pylama#GetCommand(buffer) abort
+function! ale_linters#python#pylama#GetCommand(buffer, version) abort
let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run pylama'
\ : ''
+ " json format is added in version 8.1.4
+ " https://github.com/klen/pylama/blob/develop/Changelog
+ let l:format_json_args = ale#semver#GTE(a:version, [8, 1, 4])
+ \ ? ' --format json'
+ \ : ''
+
" Note: Using %t to lint changes would be preferable, but many pylama
" checks use surrounding paths (e.g. C0103 module name, E0402 relative
" import beyond top, etc.). Neither is ideal.
return ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(ale#Var(a:buffer, 'python_pylama_options'))
+ \ . l:format_json_args
\ . ' %s'
endfunction
-function! ale_linters#python#pylama#Handle(buffer, lines) abort
+function! ale_linters#python#pylama#Handle(buffer, version, lines) abort
if empty(a:lines)
return []
endif
let l:output = ale#python#HandleTraceback(a:lines, 1)
- let l:pattern = '\v^.{-}:([0-9]+):([0-9]+): +%(([A-Z][0-9]+):? +)?(.*)$'
" First letter of error code is a pylint-compatible message type
" http://pylint.pycqa.org/en/latest/user_guide/output.html#source-code-analysis-section
@@ -75,16 +97,41 @@ function! ale_linters#python#pylama#Handle(buffer, lines) abort
\ 'D': 'style',
\}
- for l:match in ale#util#GetMatches(a:lines, l:pattern)
- call add(l:output, {
- \ 'lnum': str2nr(l:match[1]),
- \ 'col': str2nr(l:match[2]),
- \ 'code': l:match[3],
- \ 'type': get(l:pylint_type_to_ale_type, l:match[3][0], 'W'),
- \ 'sub_type': get(l:pylint_type_to_ale_sub_type, l:match[3][0], ''),
- \ 'text': l:match[4],
- \})
- endfor
+ if ale#semver#GTE(a:version, [8, 1, 4])
+ try
+ let l:errors = json_decode(join(a:lines, ''))
+ catch
+ return l:output
+ endtry
+
+ if empty(l:errors)
+ return l:output
+ endif
+
+ for l:error in l:errors
+ call add(l:output, {
+ \ 'lnum': l:error['lnum'],
+ \ 'col': l:error['col'],
+ \ 'code': l:error['number'],
+ \ 'type': get(l:pylint_type_to_ale_type, l:error['etype'], 'W'),
+ \ 'sub_type': get(l:pylint_type_to_ale_sub_type, l:error['etype'], ''),
+ \ 'text': printf('%s [%s]', l:error['message'], l:error['source']),
+ \})
+ endfor
+ else
+ let l:pattern = '\v^.{-}:([0-9]+):([0-9]+): +%(([A-Z][0-9]+):? +)?(.*)$'
+
+ for l:match in ale#util#GetMatches(a:lines, l:pattern)
+ call add(l:output, {
+ \ 'lnum': str2nr(l:match[1]),
+ \ 'col': str2nr(l:match[2]),
+ \ 'code': l:match[3],
+ \ 'type': get(l:pylint_type_to_ale_type, l:match[3][0], 'W'),
+ \ 'sub_type': get(l:pylint_type_to_ale_sub_type, l:match[3][0], ''),
+ \ 'text': l:match[4],
+ \})
+ endfor
+ endif
return l:output
endfunction
@@ -93,7 +140,15 @@ call ale#linter#Define('python', {
\ 'name': 'pylama',
\ 'executable': function('ale_linters#python#pylama#GetExecutable'),
\ 'cwd': function('ale_linters#python#pylama#GetCwd'),
-\ 'command': function('ale_linters#python#pylama#GetCommand'),
-\ 'callback': 'ale_linters#python#pylama#Handle',
+\ 'command': function('ale_linters#python#pylama#RunWithVersionCheck'),
+\ 'callback': {buffer, lines -> ale#semver#RunWithVersionCheck(
+\ buffer,
+\ ale_linters#python#pylama#GetExecutable(buffer),
+\ '%e --version',
+\ {buffer, version -> ale_linters#python#pylama#Handle(
+\ buffer,
+\ l:version,
+\ lines)},
+\ )},
\ 'lint_file': 1,
\})