12
12
import shlex
13
13
14
14
from pylsp import hookimpl , lsp
15
+ from pylsp .config .config import Config
16
+ from pylsp .workspace import Document , Workspace
17
+ from pylsp .lsp import Diagnostic , Range
15
18
16
19
try :
17
20
import ujson as json
45
48
46
49
47
50
class PylintLinter :
48
- last_diags = collections .defaultdict (list )
51
+ last_diags : dict [ str , list [ Diagnostic ]] = collections .defaultdict (list )
49
52
50
53
@classmethod
51
54
def lint (
52
- cls , document , is_saved , flags = ""
53
- ): # pylint: disable=too-many-locals,too-many-branches
55
+ cls , document : Document , is_saved : bool , flags = ""
56
+ ) -> list [ Diagnostic ] : # pylint: disable=too-many-locals,too-many-branches
54
57
"""Plugin interface to pylsp linter.
55
58
56
59
Args:
@@ -137,12 +140,12 @@ def lint(
137
140
# * fatal
138
141
# * refactor
139
142
# * warning
140
- diagnostics = []
143
+ diagnostics : list [ Diagnostic ] = []
141
144
for diag in json .loads (json_out ):
142
145
# pylint lines index from 1, pylsp lines index from 0
143
146
line = diag ["line" ] - 1
144
147
145
- err_range = {
148
+ err_range : Range = {
146
149
"start" : {
147
150
"line" : line ,
148
151
# Index columns start from 0
@@ -169,14 +172,15 @@ def lint(
169
172
elif diag ["type" ] == "warning" :
170
173
severity = lsp .DiagnosticSeverity .Warning
171
174
172
- code = diag ["message-id" ]
175
+ code : str = diag ["message-id" ]
173
176
174
- diagnostic = {
177
+ diagnostic : Diagnostic = {
175
178
"source" : "pylint" ,
176
179
"range" : err_range ,
177
180
"message" : "[{}] {}" .format (diag ["symbol" ], diag ["message" ]),
178
181
"severity" : severity ,
179
182
"code" : code ,
183
+ "tags" : [],
180
184
}
181
185
182
186
if code in UNNECESSITY_CODES :
@@ -189,7 +193,7 @@ def lint(
189
193
return diagnostics
190
194
191
195
192
- def _build_pylint_flags (settings ) :
196
+ def _build_pylint_flags (settings : dict ) -> str :
193
197
"""Build arguments for calling pylint."""
194
198
pylint_args = settings .get ("args" )
195
199
if pylint_args is None :
@@ -198,7 +202,7 @@ def _build_pylint_flags(settings):
198
202
199
203
200
204
@hookimpl
201
- def pylsp_settings ():
205
+ def pylsp_settings () -> dict :
202
206
# Default pylint to disabled because it requires a config
203
207
# file to be useful.
204
208
return {
@@ -214,22 +218,24 @@ def pylsp_settings():
214
218
215
219
216
220
@hookimpl
217
- def pylsp_lint (config , workspace , document , is_saved ):
221
+ def pylsp_lint (
222
+ config : Config , workspace : Workspace , document : Document , is_saved : bool
223
+ ) -> list [Diagnostic ]:
218
224
"""Run pylint linter."""
219
225
with workspace .report_progress ("lint: pylint" ):
220
226
settings = config .plugin_settings ("pylint" )
221
227
log .debug ("Got pylint settings: %s" , settings )
222
228
# pylint >= 2.5.0 is required for working through stdin and only
223
229
# available with python3
224
230
if settings .get ("executable" ) and sys .version_info [0 ] >= 3 :
225
- flags = build_args_stdio (settings )
231
+ flag_list = build_args_stdio (settings )
226
232
pylint_executable = settings .get ("executable" , "pylint" )
227
- return pylint_lint_stdin (pylint_executable , document , flags )
233
+ return pylint_lint_stdin (pylint_executable , document , flag_list )
228
234
flags = _build_pylint_flags (settings )
229
235
return PylintLinter .lint (document , is_saved , flags = flags )
230
236
231
237
232
- def build_args_stdio (settings ) :
238
+ def build_args_stdio (settings : dict ) -> list [ str ] :
233
239
"""Build arguments for calling pylint.
234
240
235
241
:param settings: client settings
@@ -244,7 +250,11 @@ def build_args_stdio(settings):
244
250
return pylint_args
245
251
246
252
247
- def pylint_lint_stdin (pylint_executable , document , flags ):
253
+ def pylint_lint_stdin (
254
+ pylint_executable : str ,
255
+ document : Document ,
256
+ flags : list [str ],
257
+ ) -> list [Diagnostic ]:
248
258
"""Run pylint linter from stdin.
249
259
250
260
This runs pylint in a subprocess with popen.
@@ -265,7 +275,9 @@ def pylint_lint_stdin(pylint_executable, document, flags):
265
275
return _parse_pylint_stdio_result (document , pylint_result )
266
276
267
277
268
- def _run_pylint_stdio (pylint_executable , document , flags ):
278
+ def _run_pylint_stdio (
279
+ pylint_executable : str , document : Document , flags : list [str ]
280
+ ) -> str :
269
281
"""Run pylint in popen.
270
282
271
283
:param pylint_executable: path to pylint executable
@@ -298,7 +310,7 @@ def _run_pylint_stdio(pylint_executable, document, flags):
298
310
return stdout .decode ()
299
311
300
312
301
- def _parse_pylint_stdio_result (document , stdout ) :
313
+ def _parse_pylint_stdio_result (document : Document , stdout : str ) -> list [ Diagnostic ] :
302
314
"""Parse pylint results.
303
315
304
316
:param document: document to run pylint on
@@ -309,20 +321,20 @@ def _parse_pylint_stdio_result(document, stdout):
309
321
:return: linting diagnostics
310
322
:rtype: list
311
323
"""
312
- diagnostics = []
324
+ diagnostics : list [ Diagnostic ] = []
313
325
lines = stdout .splitlines ()
314
326
for raw_line in lines :
315
327
parsed_line = re .match (r"(.*):(\d*):(\d*): (\w*): (.*)" , raw_line )
316
328
if not parsed_line :
317
329
log .debug ("Pylint output parser can't parse line '%s'" , raw_line )
318
330
continue
319
331
320
- parsed_line = parsed_line .groups ()
321
- if len (parsed_line ) != 5 :
332
+ parsed_line_groups = parsed_line .groups ()
333
+ if len (parsed_line_groups ) != 5 :
322
334
log .debug ("Pylint output parser can't parse line '%s'" , raw_line )
323
335
continue
324
336
325
- _ , line , character , code , msg = parsed_line
337
+ _ , line , character , code , msg = parsed_line_groups
326
338
line = int (line ) - 1
327
339
character = int (character )
328
340
severity_map = {
@@ -334,7 +346,7 @@ def _parse_pylint_stdio_result(document, stdout):
334
346
"W" : lsp .DiagnosticSeverity .Warning ,
335
347
}
336
348
severity = severity_map [code [0 ]]
337
- diagnostic = {
349
+ diagnostic : Diagnostic = {
338
350
"source" : "pylint" ,
339
351
"code" : code ,
340
352
"range" : {
@@ -347,6 +359,7 @@ def _parse_pylint_stdio_result(document, stdout):
347
359
},
348
360
"message" : msg ,
349
361
"severity" : severity ,
362
+ "tags" : [],
350
363
}
351
364
if code in UNNECESSITY_CODES :
352
365
diagnostic ["tags" ] = [lsp .DiagnosticTag .Unnecessary ]
0 commit comments