eric6/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py

branch
maintenance
changeset 8273
698ae46f40a4
parent 8043
0acf98cd089a
parent 8243
cc717c2ae956
equal deleted inserted replaced
8190:fb0ef164f536 8273:698ae46f40a4
10 import queue 10 import queue
11 import ast 11 import ast
12 import re 12 import re
13 import traceback 13 import traceback
14 import multiprocessing 14 import multiprocessing
15 15 import contextlib
16 16
17 try: 17 with contextlib.suppress(ImportError):
18 from pyflakes.checker import Checker 18 from pyflakes.checker import Checker
19 from pyflakes.messages import ImportStarUsed, ImportStarUsage 19 from pyflakes.messages import ImportStarUsed, ImportStarUsage
20 except ImportError:
21 pass
22 20
23 VcsConflictMarkerRegExpList = ( 21 VcsConflictMarkerRegExpList = (
24 re.compile( 22 re.compile(
25 r"""^<<<<<<< .*?\|\|\|\|\|\|\| .*?=======.*?>>>>>>> .*?$""", 23 r"""^<<<<<<< .*?\|\|\|\|\|\|\| .*?=======.*?>>>>>>> .*?$""",
26 re.MULTILINE | re.DOTALL 24 re.MULTILINE | re.DOTALL
58 @return normalized code (string) 56 @return normalized code (string)
59 """ 57 """
60 codestring = codestring.replace("\r\n", "\n").replace("\r", "\n") 58 codestring = codestring.replace("\r\n", "\n").replace("\r", "\n")
61 59
62 if codestring and codestring[-1] != '\n': 60 if codestring and codestring[-1] != '\n':
63 codestring = codestring + '\n' 61 codestring += '\n'
64 62
65 return codestring 63 return codestring
66 64
67 65
68 def extractLineFlags(line, startComment="#", endComment="", flagsLine=False): 66 def extractLineFlags(line, startComment="#", endComment="", flagsLine=False):
205 ignoreStarImportWarnings=False): 203 ignoreStarImportWarnings=False):
206 """ 204 """
207 Function to compile one Python source file to Python bytecode 205 Function to compile one Python source file to Python bytecode
208 and to perform a pyflakes check. 206 and to perform a pyflakes check.
209 207
210 @param filename source filename (string) 208 @param filename source filename
211 @param codestring string containing the code to compile (string) 209 @type str
212 @param checkFlakes flag indicating to do a pyflakes check (boolean) 210 @param codestring string containing the code to compile
211 @type str
212 @param checkFlakes flag indicating to do a pyflakes check
213 @type bool
213 @param ignoreStarImportWarnings flag indicating to 214 @param ignoreStarImportWarnings flag indicating to
214 ignore 'star import' warnings (boolean) 215 ignore 'star import' warnings
216 @type bool
215 @return dictionary with the keys 'error' and 'warnings' which 217 @return dictionary with the keys 'error' and 'warnings' which
216 hold a list containing details about the error/ warnings 218 hold a list containing details about the error/ warnings
217 (file name, line number, column, codestring (only at syntax 219 (file name, line number, column, codestring (only at syntax
218 errors), the message, a list with arguments for the message) 220 errors), the message, a list with arguments for the message)
221 @rtype dict
219 """ 222 """
220 import builtins 223 import builtins
221 224
222 try: 225 try:
223 codestring = normalizeCode(codestring) 226 codestring = normalizeCode(codestring)
276 fn = filename 279 fn = filename
277 line = 1 280 line = 1
278 error = str(detail) 281 error = str(detail)
279 return [{'error': (fn, line, 0, "", error)}] 282 return [{'error': (fn, line, 0, "", error)}]
280 except Exception as detail: 283 except Exception as detail:
281 try: 284 with contextlib.suppress(Exception):
282 fn = detail.filename 285 fn = detail.filename
283 line = detail.lineno 286 line = detail.lineno
284 error = detail.msg 287 error = detail.msg
285 return [{'error': (fn, line, 0, "", error)}] 288 return [{'error': (fn, line, 0, "", error)}]
286 except Exception: # secok
287 pass
288 289
289 # pyflakes 290 # pyflakes
290 if not checkFlakes: 291 if not checkFlakes:
291 return [{}] 292 return [{}]
292 293
294 lines = codestring.splitlines() 295 lines = codestring.splitlines()
295 try: 296 try:
296 warnings = Checker(module, filename, withDoctest=True) 297 warnings = Checker(module, filename, withDoctest=True)
297 warnings.messages.sort(key=lambda a: a.lineno) 298 warnings.messages.sort(key=lambda a: a.lineno)
298 for warning in warnings.messages: 299 for warning in warnings.messages:
299 if ignoreStarImportWarnings and ( 300 if (
300 isinstance(warning, ImportStarUsed) or 301 ignoreStarImportWarnings and
301 isinstance(warning, ImportStarUsage) 302 isinstance(warning, (ImportStarUsed, ImportStarUsage))
302 ): 303 ):
303 continue 304 continue
304 305
305 _fn, lineno, col, message, msg_args = warning.getMessageData() 306 _fn, lineno, col, message, msg_args = warning.getMessageData()
306 lineFlags = extractLineFlags(lines[lineno - 1].strip()) 307 lineFlags = extractLineFlags(lines[lineno - 1].strip())
307 try: 308 with contextlib.suppress(IndexError):
308 lineFlags += extractLineFlags(lines[lineno].strip(), 309 lineFlags += extractLineFlags(lines[lineno].strip(),
309 flagsLine=True) 310 flagsLine=True)
310 except IndexError:
311 pass
312 if ( 311 if (
313 "__IGNORE_WARNING__" not in lineFlags and 312 "__IGNORE_WARNING__" not in lineFlags and
314 "noqa" not in lineFlags 313 "noqa" not in lineFlags
315 ): 314 ):
316 results.append((_fn, lineno, col, "", message, msg_args)) 315 results.append((_fn, lineno, col, "", message, msg_args))
317 except SyntaxError as err: 316 except SyntaxError as err:
318 if err.text.strip(): 317 msg = err.text.strip() if err.text.strip() else err.msg
319 msg = err.text.strip()
320 else:
321 msg = err.msg
322 results.append((filename, err.lineno, 0, "FLAKES_ERROR", msg, [])) 318 results.append((filename, err.lineno, 0, "FLAKES_ERROR", msg, []))
323 319
324 return [{'warnings': results}] 320 return [{'warnings': results}]

eric ide

mercurial