]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/ale/ale_linters/python/mypy.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge commit 'd49e95aa7ba744f0a7f544aca43afdb6aab41f24' as '.vim/bundle/asyncomplete...
[etc/vim.git] / .vim / bundle / ale / ale_linters / python / mypy.vim
1 " Author: Keith Smiley <k@keith.so>, w0rp <devw0rp@gmail.com>
2 " Description: mypy support for optional python typechecking
3
4 call ale#Set('python_mypy_executable', 'mypy')
5 call ale#Set('python_mypy_ignore_invalid_syntax', 0)
6 call ale#Set('python_mypy_show_notes', 1)
7 call ale#Set('python_mypy_options', '')
8 call ale#Set('python_mypy_use_global', get(g:, 'ale_use_global_executables', 0))
9 call ale#Set('python_mypy_auto_pipenv', 0)
10 call ale#Set('python_mypy_auto_poetry', 0)
11 call ale#Set('python_mypy_auto_uv', 0)
12
13 function! ale_linters#python#mypy#GetExecutable(buffer) abort
14     if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_mypy_auto_pipenv'))
15     \ && ale#python#PipenvPresent(a:buffer)
16         return 'pipenv'
17     endif
18
19     if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_mypy_auto_poetry'))
20     \ && ale#python#PoetryPresent(a:buffer)
21         return 'poetry'
22     endif
23
24     if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_mypy_auto_uv'))
25     \ && ale#python#UvPresent(a:buffer)
26         return 'uv'
27     endif
28
29     return ale#python#FindExecutable(a:buffer, 'python_mypy', ['mypy'])
30 endfunction
31
32 " The directory to change to before running mypy
33 function! ale_linters#python#mypy#GetCwd(buffer) abort
34     " If we find a directory with "mypy.ini" in it use that,
35     " else try and find the "python project" root, or failing
36     " that, run from the same folder as the current file
37     for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
38         if filereadable(l:path . '/mypy.ini')
39             return l:path
40         endif
41     endfor
42
43     let l:project_root = ale#python#FindProjectRoot(a:buffer)
44
45     return !empty(l:project_root)
46     \   ? l:project_root
47     \   : expand('#' . a:buffer . ':p:h')
48 endfunction
49
50 function! ale_linters#python#mypy#GetCommand(buffer) abort
51     let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer)
52     let l:exec_args = l:executable =~? '\(pipenv\|poetry\|uv\)$'
53     \   ? ' run mypy'
54     \   : ''
55
56     return '%e' . l:exec_args
57     \   . ale#Pad(ale#Var(a:buffer, 'python_mypy_options'))
58     \   . ' --show-column-numbers'
59     \   . ' --shadow-file %s %t %s'
60 endfunction
61
62 function! ale_linters#python#mypy#Handle(buffer, lines) abort
63     let l:dir = ale_linters#python#mypy#GetCwd(a:buffer)
64     " Look for lines like the following:
65     "
66     " file.py:4: error: No library stub file for module 'django.db'
67     "
68     " Lines like these should be ignored below:
69     "
70     " file.py:4: note: (Stub files are from https://github.com/python/typeshed)
71
72     let l:types = 'error|warning'
73
74     if ale#Var(a:buffer, 'python_mypy_show_notes')
75         let l:types = 'error|warning|note'
76     endif
77
78     let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: ('
79     \   . l:types
80     \   . '): (.+)$'
81     let l:output = []
82
83     for l:match in ale#util#GetMatches(a:lines, l:pattern)
84         " Skip invalid syntax errors if the option is on.
85         if l:match[5] is# 'invalid syntax'
86         \&& ale#Var(a:buffer, 'python_mypy_ignore_invalid_syntax')
87             continue
88         endif
89
90         call add(l:output, {
91         \   'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
92         \   'lnum': l:match[2] + 0,
93         \   'col': l:match[3] + 0,
94         \   'type': l:match[4] is# 'error' ? 'E' : (l:match[4] is# 'note' ? 'I': 'W'),
95         \   'text': l:match[5],
96         \})
97     endfor
98
99     return l:output
100 endfunction
101
102 call ale#linter#Define('python', {
103 \   'name': 'mypy',
104 \   'executable': function('ale_linters#python#mypy#GetExecutable'),
105 \   'cwd': function('ale_linters#python#mypy#GetCwd'),
106 \   'command': function('ale_linters#python#mypy#GetCommand'),
107 \   'callback': 'ale_linters#python#mypy#Handle',
108 \   'output_stream': 'both'
109 \})