35 class MiscellaneousChecker(object): |
36 class MiscellaneousChecker(object): |
36 """ |
37 """ |
37 Class implementing a checker for miscellaneous checks. |
38 Class implementing a checker for miscellaneous checks. |
38 """ |
39 """ |
39 Codes = [ |
40 Codes = [ |
|
41 ## Coding line |
40 "M101", "M102", |
42 "M101", "M102", |
|
43 |
|
44 ## Copyright |
41 "M111", "M112", |
45 "M111", "M112", |
|
46 |
|
47 ## Shadowed Builtins |
42 "M131", "M132", |
48 "M131", "M132", |
43 |
49 |
|
50 ## Comprehensions |
44 "M191", "M192", "M193", "M194", |
51 "M191", "M192", "M193", "M194", |
45 "M195", "M196", "M197", "M198", |
52 "M195", "M196", "M197", "M198", |
46 |
53 |
|
54 ## Dictionaries with sorted keys |
47 "M201", |
55 "M201", |
48 |
56 |
|
57 ## Bugbear |
49 "M501", "M502", "M503", "M504", "M505", "M506", "M507", "M508", |
58 "M501", "M502", "M503", "M504", "M505", "M506", "M507", "M508", |
50 "M509", |
59 "M509", |
51 "M511", "M512", "M513", |
60 "M511", "M512", "M513", |
52 "M521", "M522", "M523", "M524", |
61 "M521", "M522", "M523", "M524", |
53 |
62 |
|
63 ## Format Strings |
54 "M601", |
64 "M601", |
55 "M611", "M612", "M613", |
65 "M611", "M612", "M613", |
56 "M621", "M622", "M623", "M624", "M625", |
66 "M621", "M622", "M623", "M624", "M625", |
57 "M631", "M632", |
67 "M631", "M632", |
|
68 |
|
69 ## Logging |
58 "M651", "M652", "M653", "M654", "M655", |
70 "M651", "M652", "M653", "M654", "M655", |
59 |
71 |
|
72 ## Future statements |
60 "M701", "M702", |
73 "M701", "M702", |
|
74 |
|
75 ## Gettext |
61 "M711", |
76 "M711", |
62 |
77 |
|
78 ## print |
63 "M801", |
79 "M801", |
|
80 |
|
81 ## one element tuple |
64 "M811", |
82 "M811", |
|
83 |
|
84 ## Mutable Defaults |
65 "M821", "M822", |
85 "M821", "M822", |
|
86 |
|
87 ## return statements |
66 "M831", "M832", "M833", "M834", |
88 "M831", "M832", "M833", "M834", |
67 |
89 |
|
90 ## line continuation |
|
91 "M841", |
|
92 |
|
93 ## commented code |
68 "M891", |
94 "M891", |
69 |
95 |
|
96 ## syntax error |
70 "M901", |
97 "M901", |
71 ] |
98 ] |
72 |
99 |
73 Formatter = Formatter() |
100 Formatter = Formatter() |
74 FormatFieldRegex = re.compile(r'^((?:\s|.)*?)(\..*|\[.*\])?$') |
101 FormatFieldRegex = re.compile(r'^((?:\s|.)*?)(\..*|\[.*\])?$') |
142 "M521", "M522", "M523", "M524")), |
169 "M521", "M522", "M523", "M524")), |
143 (self.__checkLogging, ("M651", "M652", "M653", "M654", "M655")), |
170 (self.__checkLogging, ("M651", "M652", "M653", "M654", "M655")), |
144 (self.__checkFuture, ("M701", "M702")), |
171 (self.__checkFuture, ("M701", "M702")), |
145 (self.__checkGettext, ("M711",)), |
172 (self.__checkGettext, ("M711",)), |
146 (self.__checkPrintStatements, ("M801",)), |
173 (self.__checkPrintStatements, ("M801",)), |
147 (self.__checkTuple, ("M811", )), |
174 (self.__checkTuple, ("M811",)), |
148 (self.__checkMutableDefault, ("M821", "M822")), |
175 (self.__checkMutableDefault, ("M821", "M822")), |
149 (self.__checkReturn, ("M831", "M832", "M833", "M834")), |
176 (self.__checkReturn, ("M831", "M832", "M833", "M834")), |
150 (self.__checkCommentedCode, ("M891")), |
177 (self.__checkLineContinuation, ("M841",)), |
|
178 (self.__checkCommentedCode, ("M891",)), |
151 ] |
179 ] |
152 |
180 |
153 self.__defaultArgs = { |
181 self.__defaultArgs = { |
154 "BuiltinsChecker": { |
182 "BuiltinsChecker": { |
155 "chr": ["unichr", ], |
183 "chr": ["unichr", ], |
338 "Aggressive", |
366 "Aggressive", |
339 self.__defaultArgs["CommentedCodeChecker"]["Aggressive"]) |
367 self.__defaultArgs["CommentedCodeChecker"]["Aggressive"]) |
340 for markedLine in commented_out_code_line_numbers( |
368 for markedLine in commented_out_code_line_numbers( |
341 source, aggressive=aggressive): |
369 source, aggressive=aggressive): |
342 self.__error(markedLine - 1, 0, "M891") |
370 self.__error(markedLine - 1, 0, "M891") |
|
371 |
|
372 def __checkLineContinuation(self): |
|
373 """ |
|
374 Private method to check öine continuation using '\'. |
|
375 """ |
|
376 # generate source lines without comments |
|
377 linesIterator = iter(self.__source) |
|
378 tokens = tokenize.generate_tokens(lambda: next(linesIterator)) |
|
379 comments = [token for token in tokens if token[0] == tokenize.COMMENT] |
|
380 stripped = self.__source[:] |
|
381 for comment in comments: |
|
382 lineno = comment[3][0] |
|
383 start = comment[2][1] |
|
384 stop = comment[3][1] |
|
385 content = stripped[lineno - 1] |
|
386 withoutComment = content[:start] + content[stop:] |
|
387 stripped[lineno - 1] = withoutComment.rstrip() |
|
388 |
|
389 # perform check with 'cleaned' source |
|
390 for lineIndex, line in enumerate(stripped): |
|
391 strippedLine = line.strip() |
|
392 if (strippedLine.endswith('\\') and |
|
393 not strippedLine.startswith(('assert', 'with'))): |
|
394 self.__error(lineIndex, len(line), "M841") |
343 |
395 |
344 def __checkPrintStatements(self): |
396 def __checkPrintStatements(self): |
345 """ |
397 """ |
346 Private method to check for print statements. |
398 Private method to check for print statements. |
347 """ |
399 """ |