eric6/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py

branch
maintenance
changeset 7642
72721823d453
parent 7639
422fd05e9c91
child 7900
72b88fb20261
child 7924
8a96736d465e
equal deleted inserted replaced
7608:f7cb83647621 7642:72721823d453
2 2
3 # Copyright (c) 2011 - 2020 Detlev Offenbach <detlev@die-offenbachs.de> 3 # Copyright (c) 2011 - 2020 Detlev Offenbach <detlev@die-offenbachs.de>
4 # 4 #
5 5
6 """ 6 """
7 Module implementing the syntax check for Python 2/3. 7 Module implementing the syntax check for Python 3.
8 """ 8 """
9 9
10 try: # Only for Py2 10 import queue
11 import Queue as queue
12 except ImportError:
13 import queue
14
15 import ast 11 import ast
16 import re 12 import re
17 import sys
18 import traceback 13 import traceback
19 import multiprocessing 14 import multiprocessing
20 15
21 16
22 try: 17 try:
64 """ 59 """
65 codestring = codestring.replace("\r\n", "\n").replace("\r", "\n") 60 codestring = codestring.replace("\r\n", "\n").replace("\r", "\n")
66 61
67 if codestring and codestring[-1] != '\n': 62 if codestring and codestring[-1] != '\n':
68 codestring = codestring + '\n' 63 codestring = codestring + '\n'
69
70 # Check type for py2: if not str it's unicode
71 if sys.version_info[0] == 2:
72 try:
73 codestring = codestring.encode('utf-8')
74 except UnicodeError:
75 pass
76 64
77 return codestring 65 return codestring
78 66
79 67
80 def extractLineFlags(line, startComment="#", endComment="", flagsLine=False): 68 def extractLineFlags(line, startComment="#", endComment="", flagsLine=False):
227 @return dictionary with the keys 'error' and 'warnings' which 215 @return dictionary with the keys 'error' and 'warnings' which
228 hold a list containing details about the error/ warnings 216 hold a list containing details about the error/ warnings
229 (file name, line number, column, codestring (only at syntax 217 (file name, line number, column, codestring (only at syntax
230 errors), the message, a list with arguments for the message) 218 errors), the message, a list with arguments for the message)
231 """ 219 """
220 import builtins
221
232 try: 222 try:
233 import builtins
234 except ImportError:
235 import __builtin__ as builtins # __IGNORE_WARNING__
236
237 try:
238 if sys.version_info[0] == 2:
239 file_enc = filename.encode(sys.getfilesystemencoding())
240 else:
241 file_enc = filename
242
243 # It also encode the code back to avoid 'Encoding declaration in
244 # unicode string' exception on Python2
245 codestring = normalizeCode(codestring) 223 codestring = normalizeCode(codestring)
246 224
247 # Check for VCS conflict markers 225 # Check for VCS conflict markers
248 for conflictMarkerRe in VcsConflictMarkerRegExpList: 226 for conflictMarkerRe in VcsConflictMarkerRegExpList:
249 conflict = conflictMarkerRe.search(codestring) 227 conflict = conflictMarkerRe.search(codestring)
250 if conflict is not None: 228 if conflict is not None:
251 start, i = conflict.span() 229 start, i = conflict.span()
252 lineindex = 1 + codestring.count("\n", 0, start) 230 lineindex = 1 + codestring.count("\n", 0, start)
253 return [{'error': 231 return [{'error':
254 (file_enc, lineindex, 0, "", 232 (filename, lineindex, 0, "",
255 "VCS conflict marker found") 233 "VCS conflict marker found")
256 }] 234 }]
257 235
258 if filename.endswith('.ptl'): 236 if filename.endswith('.ptl'):
259 try: 237 try:
260 import quixote.ptl_compile 238 import quixote.ptl_compile
261 except ImportError: 239 except ImportError:
262 return [{'error': (filename, 0, 0, '', 240 return [{'error': (filename, 0, 0, '',
263 'Quixote plugin not found.')}] 241 'Quixote plugin not found.')}]
264 template = quixote.ptl_compile.Template(codestring, file_enc) 242 template = quixote.ptl_compile.Template(codestring, filename)
265 template.compile() 243 template.compile()
266 else: 244 else:
267 module = builtins.compile( 245 module = builtins.compile(
268 codestring, file_enc, 'exec', ast.PyCF_ONLY_AST) 246 codestring, filename, 'exec', ast.PyCF_ONLY_AST)
269 except SyntaxError as detail: 247 except SyntaxError as detail:
270 index = 0 248 index = 0
271 code = "" 249 code = ""
272 error = "" 250 error = ""
273 lines = traceback.format_exception_only(SyntaxError, detail) 251 lines = traceback.format_exception_only(SyntaxError, detail)
274 if sys.version_info[0] == 2:
275 lines = [x.decode(sys.getfilesystemencoding()) for x in lines]
276 match = re.match(r'\s*File "(.+)", line (\d+)', 252 match = re.match(r'\s*File "(.+)", line (\d+)',
277 lines[0].replace('<string>', filename)) 253 lines[0].replace('<string>', filename))
278 if match is not None: 254 if match is not None:
279 fn, line = match.group(1, 2) 255 fn, line = match.group(1, 2)
280 if lines[1].startswith('SyntaxError:'): 256 if lines[1].startswith('SyntaxError:'):
305 try: 281 try:
306 fn = detail.filename 282 fn = detail.filename
307 line = detail.lineno 283 line = detail.lineno
308 error = detail.msg 284 error = detail.msg
309 return [{'error': (fn, line, 0, "", error)}] 285 return [{'error': (fn, line, 0, "", error)}]
310 except Exception: 286 except Exception: # secok
311 pass 287 pass
312 288
313 # pyflakes 289 # pyflakes
314 if not checkFlakes: 290 if not checkFlakes:
315 return [{}] 291 return [{}]
344 else: 320 else:
345 msg = err.msg 321 msg = err.msg
346 results.append((filename, err.lineno, 0, "FLAKES_ERROR", msg, [])) 322 results.append((filename, err.lineno, 0, "FLAKES_ERROR", msg, []))
347 323
348 return [{'warnings': results}] 324 return [{'warnings': results}]
349
350 #
351 # eflag: noqa = M702

eric ide

mercurial