Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py

changeset 5585
dab20c39f08c
parent 5389
9b1c800daff3
child 5588
6ba512d9f46a
equal deleted inserted replaced
5584:9fce9cfcbfda 5585:dab20c39f08c
20 """ 20 """
21 Codes = [ 21 Codes = [
22 "M101", "M102", 22 "M101", "M102",
23 "M111", "M112", 23 "M111", "M112",
24 "M121", 24 "M121",
25 "M131", "M132",
26
27 "M191", "M192", "M193", "M194",
28 "M195", "M196", "M197", "M198",
25 29
26 "M601", 30 "M601",
27 "M611", "M612", "M613", 31 "M611", "M612", "M613",
28 "M621", "M622", "M623", "M624", "M625", 32 "M621", "M622", "M623", "M624", "M625",
29 "M631", "M632", 33 "M631", "M632",
36 "M901", 40 "M901",
37 ] 41 ]
38 42
39 Formatter = Formatter() 43 Formatter = Formatter()
40 FormatFieldRegex = re.compile(r'^((?:\s|.)*?)(\..*|\[.*\])?$') 44 FormatFieldRegex = re.compile(r'^((?:\s|.)*?)(\..*|\[.*\])?$')
45
46 BuiltinsWhiteList = [
47 "__name__",
48 "__doc__",
49 "credits",
50 ]
41 51
42 def __init__(self, source, filename, select, ignore, expected, repeat, 52 def __init__(self, source, filename, select, ignore, expected, repeat,
43 args): 53 args):
44 """ 54 """
45 Constructor 55 Constructor
69 79
70 self.__blindExceptRegex = re.compile( 80 self.__blindExceptRegex = re.compile(
71 r'(\bexcept:)') # __IGNORE_WARNING__ 81 r'(\bexcept:)') # __IGNORE_WARNING__
72 self.__pep3101FormatRegex = re.compile( 82 self.__pep3101FormatRegex = re.compile(
73 r'^(?:[^\'"]*[\'"][^\'"]*[\'"])*\s*%|^\s*%') 83 r'^(?:[^\'"]*[\'"][^\'"]*[\'"])*\s*%|^\s*%')
84
85 if sys.version_info >= (3, 0):
86 import builtins
87 self.__builtins = [b for b in dir(builtins)
88 if b not in self.BuiltinsWhiteList]
89 else:
90 import __builtin__
91 self.__builtins = [b for b in dir(__builtin__)
92 if b not in self.BuiltinsWhiteList]
74 93
75 # statistics counters 94 # statistics counters
76 self.counters = {} 95 self.counters = {}
77 96
78 # collection of detected errors 97 # collection of detected errors
80 99
81 checkersWithCodes = [ 100 checkersWithCodes = [
82 (self.__checkCoding, ("M101", "M102")), 101 (self.__checkCoding, ("M101", "M102")),
83 (self.__checkCopyright, ("M111", "M112")), 102 (self.__checkCopyright, ("M111", "M112")),
84 (self.__checkBlindExcept, ("M121",)), 103 (self.__checkBlindExcept, ("M121",)),
104 (self.__checkBuiltins, ("M131", "M132")),
105 (self.__checkComprehensions, ("M191", "M192", "M193", "M194",
106 "M195", "M196", "M197", "M198")),
85 (self.__checkPep3101, ("M601",)), 107 (self.__checkPep3101, ("M601",)),
86 (self.__checkFormatString, ("M611", "M612", "M613", 108 (self.__checkFormatString, ("M611", "M612", "M613",
87 "M621", "M622", "M623", "M624", "M625", 109 "M621", "M622", "M623", "M624", "M625",
88 "M631", "M632")), 110 "M631", "M632")),
89 (self.__checkFuture, ("M701", "M702")), 111 (self.__checkFuture, ("M701", "M702")),
475 if parsedSpec[1] is not None) 497 if parsedSpec[1] is not None)
476 except ValueError: 498 except ValueError:
477 return set(), False, False 499 return set(), False, False
478 else: 500 else:
479 return fields, implicit, explicit 501 return fields, implicit, explicit
502
503 def __checkBuiltins(self):
504 """
505 Private method to check, if built-ins are shadowed.
506 """
507 for node in ast.walk(self.__tree):
508 if isinstance(node, ast.Assign):
509 # assign statement
510 for element in node.targets:
511 if isinstance(element, ast.Name) and \
512 element.id in self.__builtins:
513 self.__error(element.lineno - 1, element.col_offset,
514 "M131", element.id)
515 elif isinstance(node, ast.FunctionDef):
516 if sys.version_info >= (3, 0):
517 for arg in node.args.args:
518 if isinstance(arg, ast.arg) and \
519 arg.arg in self.__builtins:
520 self.__error(arg.lineno - 1, arg.col_offset,
521 "M132", arg.arg)
522 else:
523 for arg in node.args.args:
524 if isinstance(arg, ast.Name) and \
525 arg.id in self.__builtins:
526 self.__error(arg.lineno - 1, arg.col_offset,
527 "M132", arg.id)
528
529 def __checkComprehensions(self):
530 """
531 Private method to check some comprehension related things.
532 """
533 for node in ast.walk(self.__tree):
534 if (isinstance(node, ast.Call) and
535 len(node.args) == 1 and
536 isinstance(node.func, ast.Name)):
537 if (isinstance(node.args[0], ast.GeneratorExp) and
538 node.func.id in ('list', 'set', 'dict')):
539 errorCode = {
540 "list": "M191",
541 "set": "M192",
542 "dict": "M193",
543 }[node.func.id]
544 self.__error(node.lineno - 1, node.col_offset, errorCode)
545
546 elif (isinstance(node.args[0], ast.ListComp) and
547 node.func.id in ('set', 'dict')):
548 errorCode = {
549 'set': 'M194',
550 'dict': 'M195',
551 }[node.func.id]
552 self.__error(node.lineno - 1, node.col_offset, errorCode)
553
554 elif (isinstance(node.args[0], ast.List) and
555 node.func.id in ('set', 'dict')):
556 errorCode = {
557 'set': 'M196',
558 'dict': 'M197',
559 }[node.func.id]
560 self.__error(node.lineno - 1, node.col_offset, errorCode)
561
562 elif (isinstance(node.args[0], ast.ListComp) and
563 node.func.id in ('all', 'any', 'frozenset', 'max', 'min',
564 'sorted', 'sum', 'tuple',)):
565 self.__error(node.lineno - 1, node.col_offset, "M198",
566 node.func.id)
480 567
481 568
482 class TextVisitor(ast.NodeVisitor): 569 class TextVisitor(ast.NodeVisitor):
483 """ 570 """
484 Class implementing a node visitor for bytes and str instances. 571 Class implementing a node visitor for bytes and str instances.

eric ide

mercurial