3178:f25fc1364c88 | 3456:96232974dcdb |
---|---|
46 600 deprecation | 46 600 deprecation |
47 700 statements | 47 700 statements |
48 900 syntax error | 48 900 syntax error |
49 """ | 49 """ |
50 | 50 |
51 from __future__ import unicode_literals | |
52 | |
53 # | 51 # |
54 # This is a modified version to make the original pep8.py better suitable | 52 # This is a modified version to make the original pep8.py better suitable |
55 # for being called from within the eric5 IDE. The modifications are as | 53 # for being called from within the eric5 IDE. The modifications are as |
56 # follows: | 54 # follows: |
57 # | 55 # |
76 from configparser import RawConfigParser | 74 from configparser import RawConfigParser |
77 from io import TextIOWrapper | 75 from io import TextIOWrapper |
78 except ImportError: | 76 except ImportError: |
79 from ConfigParser import RawConfigParser # __IGNORE_WARNING__ | 77 from ConfigParser import RawConfigParser # __IGNORE_WARNING__ |
80 | 78 |
81 from PyQt4.QtCore import QCoreApplication, QT_TRANSLATE_NOOP | |
82 | |
83 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__' | 79 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__' |
84 DEFAULT_IGNORE = 'E123,E226,E24' | 80 DEFAULT_IGNORE = 'E123,E226,E24' |
85 if sys.platform == 'win32': | 81 if sys.platform == 'win32': |
86 DEFAULT_CONFIG = os.path.expanduser(r'~\.pep8') | 82 DEFAULT_CONFIG = os.path.expanduser(r'~\.pep8') |
87 else: | 83 else: |
128 # a comment which is on a line by itself. | 124 # a comment which is on a line by itself. |
129 COMMENT_WITH_NL = tokenize.generate_tokens(['#\n'].pop).send(None)[1] == '#\n' | 125 COMMENT_WITH_NL = tokenize.generate_tokens(['#\n'].pop).send(None)[1] == '#\n' |
130 | 126 |
131 | 127 |
132 ############################################################################## | 128 ############################################################################## |
133 # Helper functions for translated and formatted messages | |
134 ############################################################################## | |
135 | |
136 | |
137 pep8_messages = { | |
138 "E101": QT_TRANSLATE_NOOP("pep8", | |
139 "indentation contains mixed spaces and tabs"), | |
140 "E111": QT_TRANSLATE_NOOP("pep8", | |
141 "indentation is not a multiple of four"), | |
142 "E112": QT_TRANSLATE_NOOP("pep8", | |
143 "expected an indented block"), | |
144 "E113": QT_TRANSLATE_NOOP("pep8", | |
145 "unexpected indentation"), | |
146 "E121": QT_TRANSLATE_NOOP("pep8", | |
147 "continuation line indentation is not a multiple of four"), | |
148 "E122": QT_TRANSLATE_NOOP("pep8", | |
149 "continuation line missing indentation or outdented"), | |
150 "E123": QT_TRANSLATE_NOOP("pep8", | |
151 "closing bracket does not match indentation of opening" | |
152 " bracket's line"), | |
153 "E124": QT_TRANSLATE_NOOP("pep8", | |
154 "closing bracket does not match visual indentation"), | |
155 "E125": QT_TRANSLATE_NOOP("pep8", | |
156 "continuation line does not distinguish itself from next" | |
157 " logical line"), | |
158 "E126": QT_TRANSLATE_NOOP("pep8", | |
159 "continuation line over-indented for hanging indent"), | |
160 "E127": QT_TRANSLATE_NOOP("pep8", | |
161 "continuation line over-indented for visual indent"), | |
162 "E128": QT_TRANSLATE_NOOP("pep8", | |
163 "continuation line under-indented for visual indent"), | |
164 "E133": QT_TRANSLATE_NOOP("pep8", | |
165 "closing bracket is missing indentation"), | |
166 "W191": QT_TRANSLATE_NOOP("pep8", | |
167 "indentation contains tabs"), | |
168 "E201": QT_TRANSLATE_NOOP("pep8", | |
169 "whitespace after '{0}'"), | |
170 "E202": QT_TRANSLATE_NOOP("pep8", | |
171 "whitespace before '{0}'"), | |
172 "E203": QT_TRANSLATE_NOOP("pep8", | |
173 "whitespace before '{0}'"), | |
174 "E211": QT_TRANSLATE_NOOP("pep8", | |
175 "whitespace before '{0}'"), | |
176 "E221": QT_TRANSLATE_NOOP("pep8", | |
177 "multiple spaces before operator"), | |
178 "E222": QT_TRANSLATE_NOOP("pep8", | |
179 "multiple spaces after operator"), | |
180 "E223": QT_TRANSLATE_NOOP("pep8", | |
181 "tab before operator"), | |
182 "E224": QT_TRANSLATE_NOOP("pep8", | |
183 "tab after operator"), | |
184 "E225": QT_TRANSLATE_NOOP("pep8", | |
185 "missing whitespace around operator"), | |
186 "E226": QT_TRANSLATE_NOOP("pep8", | |
187 "missing whitespace around arithmetic operator"), | |
188 "E227": QT_TRANSLATE_NOOP("pep8", | |
189 "missing whitespace around bitwise or shift operator"), | |
190 "E228": QT_TRANSLATE_NOOP("pep8", | |
191 "missing whitespace around modulo operator"), | |
192 "E231": QT_TRANSLATE_NOOP("pep8", | |
193 "missing whitespace after '{0}'"), | |
194 "E241": QT_TRANSLATE_NOOP("pep8", | |
195 "multiple spaces after '{0}'"), | |
196 "E242": QT_TRANSLATE_NOOP("pep8", | |
197 "tab after '{0}'"), | |
198 "E251": QT_TRANSLATE_NOOP("pep8", | |
199 "unexpected spaces around keyword / parameter equals"), | |
200 "E261": QT_TRANSLATE_NOOP("pep8", | |
201 "at least two spaces before inline comment"), | |
202 "E262": QT_TRANSLATE_NOOP("pep8", | |
203 "inline comment should start with '# '"), | |
204 "E271": QT_TRANSLATE_NOOP("pep8", | |
205 "multiple spaces after keyword"), | |
206 "E272": QT_TRANSLATE_NOOP("pep8", | |
207 "multiple spaces before keyword"), | |
208 "E273": QT_TRANSLATE_NOOP("pep8", | |
209 "tab after keyword"), | |
210 "E274": QT_TRANSLATE_NOOP("pep8", | |
211 "tab before keyword"), | |
212 "W291": QT_TRANSLATE_NOOP("pep8", | |
213 "trailing whitespace"), | |
214 "W292": QT_TRANSLATE_NOOP("pep8", | |
215 "no newline at end of file"), | |
216 "W293": QT_TRANSLATE_NOOP("pep8", | |
217 "blank line contains whitespace"), | |
218 "E301": QT_TRANSLATE_NOOP("pep8", | |
219 "expected 1 blank line, found 0"), | |
220 "E302": QT_TRANSLATE_NOOP("pep8", | |
221 "expected 2 blank lines, found {0}"), | |
222 "E303": QT_TRANSLATE_NOOP("pep8", | |
223 "too many blank lines ({0})"), | |
224 "E304": QT_TRANSLATE_NOOP("pep8", | |
225 "blank lines found after function decorator"), | |
226 "W391": QT_TRANSLATE_NOOP("pep8", | |
227 "blank line at end of file"), | |
228 "E401": QT_TRANSLATE_NOOP("pep8", | |
229 "multiple imports on one line"), | |
230 "E501": QT_TRANSLATE_NOOP("pep8", | |
231 "line too long ({0} > {1} characters)"), | |
232 "E502": QT_TRANSLATE_NOOP("pep8", | |
233 "the backslash is redundant between brackets"), | |
234 "W601": QT_TRANSLATE_NOOP("pep8", | |
235 ".has_key() is deprecated, use 'in'"), | |
236 "W602": QT_TRANSLATE_NOOP("pep8", | |
237 "deprecated form of raising exception"), | |
238 "W603": QT_TRANSLATE_NOOP("pep8", | |
239 "'<>' is deprecated, use '!='"), | |
240 "W604": QT_TRANSLATE_NOOP("pep8", | |
241 "backticks are deprecated, use 'repr()'"), | |
242 "E701": QT_TRANSLATE_NOOP("pep8", | |
243 "multiple statements on one line (colon)"), | |
244 "E702": QT_TRANSLATE_NOOP("pep8", | |
245 "multiple statements on one line (semicolon)"), | |
246 "E703": QT_TRANSLATE_NOOP("pep8", | |
247 "statement ends with a semicolon"), | |
248 "E711": QT_TRANSLATE_NOOP("pep8", | |
249 "comparison to {0} should be {1}"), | |
250 "E712": QT_TRANSLATE_NOOP("pep8", | |
251 "comparison to {0} should be {1}"), | |
252 "E721": QT_TRANSLATE_NOOP("pep8", | |
253 "do not compare types, use 'isinstance()'"), | |
254 "E901": QT_TRANSLATE_NOOP("pep8", | |
255 "{0}: {1}"), | |
256 } | |
257 | |
258 pep8_messages_sample_args = { | |
259 "E201": ["([{"], | |
260 "E202": ["}])"], | |
261 "E203": [",;:"], | |
262 "E211": ["(["], | |
263 "E231": [",;:"], | |
264 "E241": [",;:"], | |
265 "E242": [",;:"], | |
266 "E302": [1], | |
267 "E303": [3], | |
268 "E501": [85, 79], | |
269 "E711": ["None", "'if cond is None:'"], | |
270 "E712": ["True", "'if cond is True:' or 'if cond:'"], | |
271 "E901": ["SyntaxError", "Invalid Syntax"], | |
272 } | |
273 | |
274 | |
275 def getMessage(code, *args): | |
276 """ | |
277 Function to get a translated and formatted message for a given code. | |
278 | |
279 @param code message code (string) | |
280 @param args arguments for a formatted message (list) | |
281 @return translated and formatted message (string) | |
282 """ | |
283 if code in pep8_messages: | |
284 return code + " " + QCoreApplication.translate("pep8", | |
285 pep8_messages[code]).format(*args) | |
286 else: | |
287 return code + " " + QCoreApplication.translate("pep8", | |
288 "no message for this code defined") | |
289 | |
290 ############################################################################## | |
291 # Plugins (check functions) for physical lines | 129 # Plugins (check functions) for physical lines |
292 ############################################################################## | 130 ############################################################################## |
293 | 131 |
294 | 132 |
295 def tabs_or_spaces(physical_line, indent_char): | 133 def tabs_or_spaces(physical_line, indent_char): |
394 if length > max_line_length and not noqa(line): | 232 if length > max_line_length and not noqa(line): |
395 if hasattr(line, 'decode'): # Python 2 | 233 if hasattr(line, 'decode'): # Python 2 |
396 # The line could contain multi-byte characters | 234 # The line could contain multi-byte characters |
397 try: | 235 try: |
398 length = len(line.decode('utf-8')) | 236 length = len(line.decode('utf-8')) |
399 except (UnicodeDecodeError, UnicodeEncodeError): | 237 except UnicodeError: |
400 pass | 238 pass |
401 if length > max_line_length: | 239 if length > max_line_length: |
402 return max_line_length, "E501", length, max_line_length | 240 return max_line_length, "E501", length, max_line_length |
403 | 241 |
404 | 242 |
779 | 617 |
780 if '\t' in after: | 618 if '\t' in after: |
781 yield match.start(2), "E224" | 619 yield match.start(2), "E224" |
782 elif len(after) > 1: | 620 elif len(after) > 1: |
783 yield match.start(2), "E222" | 621 yield match.start(2), "E222" |
622 | |
784 | 623 |
785 def missing_whitespace_around_operator(logical_line, tokens): | 624 def missing_whitespace_around_operator(logical_line, tokens): |
786 r""" | 625 r""" |
787 - Always surround these binary operators with a single space on | 626 - Always surround these binary operators with a single space on |
788 either side: assignment (=), augmented assignment (+=, -= etc.), | 627 either side: assignment (=), augmented assignment (+=, -= etc.), |
1437 for name, check, argument_names in self._physical_checks: | 1276 for name, check, argument_names in self._physical_checks: |
1438 result = self.run_check(check, argument_names) | 1277 result = self.run_check(check, argument_names) |
1439 if result is not None: | 1278 if result is not None: |
1440 offset, code = result[:2] | 1279 offset, code = result[:2] |
1441 args = result[2:] | 1280 args = result[2:] |
1442 self.report_error_args(self.line_number, offset, code, check, | 1281 self.report_error_args( |
1443 *args) | 1282 self.line_number, offset, code, check, *args) |
1444 | 1283 |
1445 def build_tokens_line(self): | 1284 def build_tokens_line(self): |
1446 """ | 1285 """ |
1447 Build a logical line from tokens. | 1286 Build a logical line from tokens. |
1448 """ | 1287 """ |
1505 else: | 1344 else: |
1506 for token_offset, token in self.mapping: | 1345 for token_offset, token in self.mapping: |
1507 if offset >= token_offset: | 1346 if offset >= token_offset: |
1508 orig_number = token[2][0] | 1347 orig_number = token[2][0] |
1509 orig_offset = (token[2][1] + offset - token_offset) | 1348 orig_offset = (token[2][1] + offset - token_offset) |
1510 self.report_error_args(orig_number, orig_offset, code, check, | 1349 self.report_error_args( |
1511 *args) | 1350 orig_number, orig_offset, code, check, *args) |
1512 self.previous_logical = self.logical_line | 1351 self.previous_logical = self.logical_line |
1513 | 1352 |
1514 def check_ast(self): | 1353 def check_ast(self): |
1515 try: | 1354 try: |
1516 tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST) | 1355 tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST) |
1627 return | 1466 return |
1628 if code in self.counters: | 1467 if code in self.counters: |
1629 self.counters[code] += 1 | 1468 self.counters[code] += 1 |
1630 else: | 1469 else: |
1631 self.counters[code] = 1 | 1470 self.counters[code] = 1 |
1632 self.messages[code] = text[5:] | 1471 self.messages[code] = [] |
1633 # Don't care about expected errors or warnings | 1472 # Don't care about expected errors or warnings |
1634 if code in self.expected: | 1473 if code in self.expected: |
1635 return | 1474 return |
1636 if self.print_filename and not self.file_errors: | 1475 if self.print_filename and not self.file_errors: |
1637 print(self.filename) | 1476 print(self.filename) |
1641 | 1480 |
1642 def error_args(self, line_number, offset, code, check, *args): | 1481 def error_args(self, line_number, offset, code, check, *args): |
1643 """Report an error, according to options.""" | 1482 """Report an error, according to options.""" |
1644 if self._ignore_code(code): | 1483 if self._ignore_code(code): |
1645 return | 1484 return |
1646 text = getMessage(code, *args) | |
1647 if code in self.counters: | 1485 if code in self.counters: |
1648 self.counters[code] += 1 | 1486 self.counters[code] += 1 |
1649 else: | 1487 else: |
1650 self.counters[code] = 1 | 1488 self.counters[code] = 1 |
1651 self.messages[code] = text[5:] | 1489 self.messages[code] = args |
1652 # Don't care about expected errors or warnings | 1490 # Don't care about expected errors or warnings |
1653 if code in self.expected: | 1491 if code in self.expected: |
1654 return | 1492 return |
1655 if self.print_filename and not self.file_errors: | 1493 if self.print_filename and not self.file_errors: |
1656 print(self.filename) | 1494 print(self.filename) |
1728 def error_args(self, line_number, offset, code, check, *args): | 1566 def error_args(self, line_number, offset, code, check, *args): |
1729 """Report an error, according to options.""" | 1567 """Report an error, according to options.""" |
1730 code = super(StandardReport, self).error_args(line_number, offset, | 1568 code = super(StandardReport, self).error_args(line_number, offset, |
1731 code, check, *args) | 1569 code, check, *args) |
1732 if code and (self.counters[code] == 1 or self._repeat): | 1570 if code and (self.counters[code] == 1 or self._repeat): |
1733 text = getMessage(code, *args) | |
1734 self._deferred_print.append( | 1571 self._deferred_print.append( |
1735 (line_number, offset, code, text[5:], check.__doc__)) | 1572 (line_number, offset, code, args, check.__doc__)) |
1736 return code | 1573 return code |
1737 | 1574 |
1738 def get_file_results(self): | 1575 def get_file_results(self): |
1739 """Print the result and return the overall count for this file.""" | 1576 """Print the result and return the overall count for this file.""" |
1740 self._deferred_print.sort() | 1577 self._deferred_print.sort() |