src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Simplify/SimplifyChecker.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9277
471c5a263d53
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
15 15
16 class SimplifyChecker: 16 class SimplifyChecker:
17 """ 17 """
18 Class implementing a checker for to help simplifying Python code. 18 Class implementing a checker for to help simplifying Python code.
19 """ 19 """
20
20 Codes = [ 21 Codes = [
21 # Python-specifics 22 # Python-specifics
22 "Y101", "Y102", "Y103", "Y104", "Y105", "Y106", "Y107", "Y108", 23 "Y101",
23 "Y109", "Y110", "Y111", "Y112", "Y113", "Y114", "Y115", "Y116", 24 "Y102",
24 "Y117", "Y118", "Y119", "Y120", "Y121", "Y122", 25 "Y103",
25 26 "Y104",
27 "Y105",
28 "Y106",
29 "Y107",
30 "Y108",
31 "Y109",
32 "Y110",
33 "Y111",
34 "Y112",
35 "Y113",
36 "Y114",
37 "Y115",
38 "Y116",
39 "Y117",
40 "Y118",
41 "Y119",
42 "Y120",
43 "Y121",
44 "Y122",
26 # Python-specifics not part of flake8-simplify 45 # Python-specifics not part of flake8-simplify
27 "Y181", "Y182", 46 "Y181",
28 47 "Y182",
29 # Comparations 48 # Comparations
30 "Y201", "Y202", "Y203", "Y204", "Y205", "Y206", "Y207", "Y208", 49 "Y201",
31 "Y211", "Y212", "Y213", 50 "Y202",
32 "Y221", "Y222", "Y223", "Y224", 51 "Y203",
33 52 "Y204",
53 "Y205",
54 "Y206",
55 "Y207",
56 "Y208",
57 "Y211",
58 "Y212",
59 "Y213",
60 "Y221",
61 "Y222",
62 "Y223",
63 "Y224",
34 # Opinionated 64 # Opinionated
35 "Y301", 65 "Y301",
36
37 # General Code Style 66 # General Code Style
38 "Y401", "Y402", 67 "Y401",
68 "Y402",
39 ] 69 ]
40 70
41 def __init__(self, source, filename, tree, selected, ignored, expected, 71 def __init__(self, source, filename, tree, selected, ignored, expected, repeat):
42 repeat):
43 """ 72 """
44 Constructor 73 Constructor
45 74
46 @param source source code to be checked 75 @param source source code to be checked
47 @type list of str 76 @type list of str
48 @param filename name of the source file 77 @param filename name of the source file
49 @type str 78 @type str
50 @param tree AST tree of the source code 79 @param tree AST tree of the source code
57 @type list of str 86 @type list of str
58 @param repeat flag indicating to report each occurrence of a code 87 @param repeat flag indicating to report each occurrence of a code
59 @type bool 88 @type bool
60 """ 89 """
61 self.__select = tuple(selected) 90 self.__select = tuple(selected)
62 self.__ignore = ('',) if selected else tuple(ignored) 91 self.__ignore = ("",) if selected else tuple(ignored)
63 self.__expected = expected[:] 92 self.__expected = expected[:]
64 self.__repeat = repeat 93 self.__repeat = repeat
65 self.__filename = filename 94 self.__filename = filename
66 self.__source = source[:] 95 self.__source = source[:]
67 self.__tree = copy.deepcopy(tree) 96 self.__tree = copy.deepcopy(tree)
68 97
69 # statistics counters 98 # statistics counters
70 self.counters = {} 99 self.counters = {}
71 100
72 # collection of detected errors 101 # collection of detected errors
73 self.errors = [] 102 self.errors = []
74 103
75 self.__checkCodes = (code for code in self.Codes 104 self.__checkCodes = (code for code in self.Codes if not self.__ignoreCode(code))
76 if not self.__ignoreCode(code)) 105
77
78 def __ignoreCode(self, code): 106 def __ignoreCode(self, code):
79 """ 107 """
80 Private method to check if the message code should be ignored. 108 Private method to check if the message code should be ignored.
81 109
82 @param code message code to check for 110 @param code message code to check for
83 @type str 111 @type str
84 @return flag indicating to ignore the given code 112 @return flag indicating to ignore the given code
85 @rtype bool 113 @rtype bool
86 """ 114 """
87 return (code.startswith(self.__ignore) and 115 return code.startswith(self.__ignore) and not code.startswith(self.__select)
88 not code.startswith(self.__select)) 116
89
90 def __error(self, lineNumber, offset, code, *args): 117 def __error(self, lineNumber, offset, code, *args):
91 """ 118 """
92 Private method to record an issue. 119 Private method to record an issue.
93 120
94 @param lineNumber line number of the issue 121 @param lineNumber line number of the issue
95 @type int 122 @type int
96 @param offset position within line of the issue 123 @param offset position within line of the issue
97 @type int 124 @type int
98 @param code message code 125 @param code message code
100 @param args arguments for the message 127 @param args arguments for the message
101 @type list 128 @type list
102 """ 129 """
103 if self.__ignoreCode(code): 130 if self.__ignoreCode(code):
104 return 131 return
105 132
106 # record the issue with one based line number 133 # record the issue with one based line number
107 errorInfo = { 134 errorInfo = {
108 "file": self.__filename, 135 "file": self.__filename,
109 "line": lineNumber + 1, 136 "line": lineNumber + 1,
110 "offset": offset, 137 "offset": offset,
111 "code": code, 138 "code": code,
112 "args": args, 139 "args": args,
113 } 140 }
114 141
115 if errorInfo not in self.errors: 142 if errorInfo not in self.errors:
116 # this issue was not seen before 143 # this issue was not seen before
117 if code in self.counters: 144 if code in self.counters:
118 self.counters[code] += 1 145 self.counters[code] += 1
119 else: 146 else:
120 self.counters[code] = 1 147 self.counters[code] = 1
121 148
122 # Don't care about expected codes 149 # Don't care about expected codes
123 if code in self.__expected: 150 if code in self.__expected:
124 return 151 return
125 152
126 if code and (self.counters[code] == 1 or self.__repeat): 153 if code and (self.counters[code] == 1 or self.__repeat):
127 self.errors.append(errorInfo) 154 self.errors.append(errorInfo)
128 155
129 def run(self): 156 def run(self):
130 """ 157 """
131 Public method to check the given source against functions 158 Public method to check the given source against functions
132 to be replaced by 'pathlib' equivalents. 159 to be replaced by 'pathlib' equivalents.
133 """ 160 """
134 if not self.__filename: 161 if not self.__filename:
135 # don't do anything, if essential data is missing 162 # don't do anything, if essential data is missing
136 return 163 return
137 164
138 if not self.__checkCodes: 165 if not self.__checkCodes:
139 # don't do anything, if no codes were selected 166 # don't do anything, if no codes were selected
140 return 167 return
141 168
142 # Add parent information 169 # Add parent information
143 for node in ast.walk(self.__tree): 170 for node in ast.walk(self.__tree):
144 for child in ast.iter_child_nodes(node): 171 for child in ast.iter_child_nodes(node):
145 child.parent = node # type: ignore 172 child.parent = node # type: ignore
146 173
147 visitor = SimplifyNodeVisitor(self.__error) 174 visitor = SimplifyNodeVisitor(self.__error)
148 visitor.visit(self.__tree) 175 visitor.visit(self.__tree)

eric ide

mercurial