eric6/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py

changeset 8198
1c765dc90c21
parent 8194
b925628bf91f
child 8205
4a0f1f896341
equal deleted inserted replaced
8197:9037d09ed87c 8198:1c765dc90c21
277 277
278 @param filename source filename 278 @param filename source filename
279 @type str 279 @type str
280 @param source string containing the code to check 280 @param source string containing the code to check
281 @type str 281 @type str
282 @return tuple containing the error dictionary with syntax error details 282 @return tuple containing the error dictionary with syntax error details,
283 and a statistics dictionary or a tuple containing two None 283 a statistics dictionary and None or a tuple containing two None and
284 @rtype tuple of (dict, dict) or tuple of (None, None) 284 the generated AST tree
285 @rtype tuple of (dict, dict, None) or tuple of (None, None, ast.Module)
285 """ 286 """
286 src = "".join(source) 287 src = "".join(source)
287 288
288 try: 289 try:
289 ast.parse(src, filename, 'exec') 290 tree = ast.parse(src, filename, 'exec')
290 return None, None 291 return None, None, tree
291 except (SyntaxError, TypeError): 292 except (SyntaxError, TypeError):
292 exc_type, exc = sys.exc_info()[:2] 293 exc_type, exc = sys.exc_info()[:2]
293 if len(exc.args) > 1: 294 if len(exc.args) > 1:
294 offset = exc.args[1] 295 offset = exc.args[1]
295 if len(offset) > 2: 296 if len(offset) > 2:
302 "offset": offset[1], 303 "offset": offset[1],
303 "code": "E901", 304 "code": "E901",
304 "args": [exc_type.__name__, exc.args[0]], 305 "args": [exc_type.__name__, exc.args[0]],
305 }, { 306 }, {
306 "E901": 1, 307 "E901": 1,
307 }) 308 },
309 None)
308 310
309 311
310 def __checkCodeStyle(filename, source, args): 312 def __checkCodeStyle(filename, source, args):
311 """ 313 """
312 Private module function to perform the code style check and/or fix 314 Private module function to perform the code style check and/or fix
365 ignore = [i.strip() for i in 367 ignore = [i.strip() for i in
366 excludeMessages.split(',') if i.strip()] 368 excludeMessages.split(',') if i.strip()]
367 else: 369 else:
368 ignore = [] 370 ignore = []
369 371
370 syntaxError, syntaxStats = __checkSyntax(filename, source) 372 syntaxError, syntaxStats, tree = __checkSyntax(filename, source)
371 if syntaxError: 373
372 errors = [syntaxError] 374 # perform the checks only, if syntax is ok and AST tree was generated
373 stats.update(syntaxStats) 375 if tree:
374
375 # perform the checks only, if syntax is ok
376 else:
377 # check coding style 376 # check coding style
378 pycodestyle.BLANK_LINES_CONFIG = { 377 pycodestyle.BLANK_LINES_CONFIG = {
379 # Top level class and function. 378 # Top level class and function.
380 'top_level': blankLines[0], 379 'top_level': blankLines[0],
381 # Methods and nested class and function. 380 # Methods and nested class and function.
402 stats.update(docStyleChecker.counters) 401 stats.update(docStyleChecker.counters)
403 errors += docStyleChecker.errors 402 errors += docStyleChecker.errors
404 403
405 # miscellaneous additional checks 404 # miscellaneous additional checks
406 miscellaneousChecker = MiscellaneousChecker( 405 miscellaneousChecker = MiscellaneousChecker(
407 source, filename, select, ignore, [], repeatMessages, 406 source, filename, tree, select, ignore, [], repeatMessages,
408 miscellaneousArgs) 407 miscellaneousArgs)
409 miscellaneousChecker.run() 408 miscellaneousChecker.run()
410 stats.update(miscellaneousChecker.counters) 409 stats.update(miscellaneousChecker.counters)
411 errors += miscellaneousChecker.errors 410 errors += miscellaneousChecker.errors
412 411
413 # check code complexity 412 # check code complexity
414 complexityChecker = ComplexityChecker( 413 complexityChecker = ComplexityChecker(
415 source, filename, select, ignore, codeComplexityArgs) 414 source, filename, tree, select, ignore, codeComplexityArgs)
416 complexityChecker.run() 415 complexityChecker.run()
417 stats.update(complexityChecker.counters) 416 stats.update(complexityChecker.counters)
418 errors += complexityChecker.errors 417 errors += complexityChecker.errors
419 418
420 # check function annotations 419 # check function annotations
421 if sys.version_info >= (3, 5, 0): 420 if sys.version_info >= (3, 5, 0):
422 # annotations are supported from Python 3.5 on 421 # annotations are supported from Python 3.5 on
423 from Annotations.AnnotationsChecker import AnnotationsChecker 422 from Annotations.AnnotationsChecker import AnnotationsChecker
424 annotationsChecker = AnnotationsChecker( 423 annotationsChecker = AnnotationsChecker(
425 source, filename, select, ignore, [], repeatMessages, 424 source, filename, tree, select, ignore, [], repeatMessages,
426 annotationArgs) 425 annotationArgs)
427 annotationsChecker.run() 426 annotationsChecker.run()
428 stats.update(annotationsChecker.counters) 427 stats.update(annotationsChecker.counters)
429 errors += annotationsChecker.errors 428 errors += annotationsChecker.errors
430 429
431 # check for security issues 430 # check for security issues
432 securityChecker = SecurityChecker( 431 securityChecker = SecurityChecker(
433 source, filename, select, ignore, [], repeatMessages, 432 source, filename, tree, select, ignore, [], repeatMessages,
434 securityArgs) 433 securityArgs)
435 securityChecker.run() 434 securityChecker.run()
436 stats.update(securityChecker.counters) 435 stats.update(securityChecker.counters)
437 errors += securityChecker.errors 436 errors += securityChecker.errors
438 437
439 # check for pathlib usage 438 # check for pathlib usage
440 pathlibChecker = PathlibChecker( 439 pathlibChecker = PathlibChecker(
441 source, filename, select, ignore, [], repeatMessages) 440 source, filename, tree, select, ignore, [], repeatMessages)
442 pathlibChecker.run() 441 pathlibChecker.run()
443 stats.update(pathlibChecker.counters) 442 stats.update(pathlibChecker.counters)
444 errors += pathlibChecker.errors 443 errors += pathlibChecker.errors
445 444
446 # check for code simplifications 445 # check for code simplifications
447 simplifyChecker = SimplifyChecker( 446 simplifyChecker = SimplifyChecker(
448 source, filename, select, ignore, [], repeatMessages) 447 source, filename, tree, select, ignore, [], repeatMessages)
449 simplifyChecker.run() 448 simplifyChecker.run()
450 stats.update(simplifyChecker.counters) 449 stats.update(simplifyChecker.counters)
451 errors += simplifyChecker.errors 450 errors += simplifyChecker.errors
451
452 elif syntaxError:
453 errors = [syntaxError]
454 stats.update(syntaxStats)
452 455
453 errorsDict = {} 456 errorsDict = {}
454 for error in errors: 457 for error in errors:
455 if error["line"] > len(source): 458 if error["line"] > len(source):
456 error["line"] = len(source) 459 error["line"] = len(source)

eric ide

mercurial