88 from configparser import RawConfigParser |
88 from configparser import RawConfigParser |
89 from io import TextIOWrapper |
89 from io import TextIOWrapper |
90 except ImportError: |
90 except ImportError: |
91 from ConfigParser import RawConfigParser # __IGNORE_WARNING__ |
91 from ConfigParser import RawConfigParser # __IGNORE_WARNING__ |
92 |
92 |
93 __version__ = '2.6.0-eric' |
93 __version__ = '2.7.0-eric' |
94 |
94 |
95 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' |
95 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' |
96 DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504' |
96 DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504' |
97 try: |
97 try: |
98 if sys.platform == 'win32': |
98 if sys.platform == 'win32': |
274 W391: spam(1)\n |
275 W391: spam(1)\n |
275 |
276 |
276 However the last line should end with a new line (warning W292). |
277 However the last line should end with a new line (warning W292). |
277 """ |
278 """ |
278 if line_number == total_lines: |
279 if line_number == total_lines: |
279 stripped_last_line = physical_line.rstrip() |
280 stripped_last_line = physical_line.rstrip('\r\n') |
280 if physical_line and not stripped_last_line: |
281 if physical_line and not stripped_last_line: |
281 return 0, "W391 blank line at end of file" |
282 return 0, "W391 blank line at end of file" |
282 if stripped_last_line == physical_line: |
283 if stripped_last_line == physical_line: |
283 return len(lines[-1]), "W292 no newline at end of file" |
284 return len(lines[-1]), "W292 no newline at end of file" |
284 |
285 |
565 yield index, "E231 missing whitespace after '%s'", char |
566 yield index, "E231 missing whitespace after '%s'", char |
566 |
567 |
567 |
568 |
568 @register_check |
569 @register_check |
569 def indentation(logical_line, previous_logical, indent_char, |
570 def indentation(logical_line, previous_logical, indent_char, |
570 indent_level, previous_indent_level): |
571 indent_level, previous_indent_level, |
571 r"""Use 4 spaces per indentation level. |
572 indent_size, indent_size_str): |
|
573 r"""Use indent_size (PEP8 says 4) spaces per indentation level. |
572 |
574 |
573 For really old code that you don't want to mess up, you can continue |
575 For really old code that you don't want to mess up, you can continue |
574 to use 8-space tabs. |
576 to use 8-space tabs. |
575 |
577 |
576 Okay: a = 1 |
578 Okay: a = 1 |
586 E113: a = 1\n b = 2 |
588 E113: a = 1\n b = 2 |
587 E116: a = 1\n # b = 2 |
589 E116: a = 1\n # b = 2 |
588 """ |
590 """ |
589 c = 0 if logical_line else 3 |
591 c = 0 if logical_line else 3 |
590 tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)" |
592 tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)" |
591 if indent_level % 4: |
593 if indent_level % indent_size: |
592 yield 0, tmpl % (1 + c, "indentation is not a multiple of four") |
594 yield 0, tmpl % ( |
|
595 1 + c, |
|
596 "indentation is not a multiple of " + indent_size_str, |
|
597 ) |
593 indent_expect = previous_logical.endswith(':') |
598 indent_expect = previous_logical.endswith(':') |
594 if indent_expect and indent_level <= previous_indent_level: |
599 if indent_expect and indent_level <= previous_indent_level: |
595 yield 0, tmpl % (2 + c, "expected an indented block") |
600 yield 0, tmpl % (2 + c, "expected an indented block") |
596 elif not indent_expect and indent_level > previous_indent_level: |
601 elif not indent_expect and indent_level > previous_indent_level: |
597 yield 0, tmpl % (3 + c, "unexpected indentation") |
602 yield 0, tmpl % (3 + c, "unexpected indentation") |
603 yield 0, tmpl % (7, 'over-indented') |
608 yield 0, tmpl % (7, 'over-indented') |
604 |
609 |
605 |
610 |
606 @register_check |
611 @register_check |
607 def continued_indentation(logical_line, tokens, indent_level, hang_closing, |
612 def continued_indentation(logical_line, tokens, indent_level, hang_closing, |
608 indent_char, noqa, verbose): |
613 indent_char, indent_size, indent_size_str, noqa, |
|
614 verbose): |
609 r"""Continuation lines indentation. |
615 r"""Continuation lines indentation. |
610 |
616 |
611 Continuation lines should align wrapped elements either vertically |
617 Continuation lines should align wrapped elements either vertically |
612 using Python's implicit line joining inside parentheses, brackets |
618 using Python's implicit line joining inside parentheses, brackets |
613 and braces, or using a hanging indent. |
619 and braces, or using a hanging indent. |
642 # indents on the final continuation line; in turn, some other |
648 # indents on the final continuation line; in turn, some other |
643 # indents are allowed to have an extra 4 spaces. |
649 # indents are allowed to have an extra 4 spaces. |
644 indent_next = logical_line.endswith(':') |
650 indent_next = logical_line.endswith(':') |
645 |
651 |
646 row = depth = 0 |
652 row = depth = 0 |
647 valid_hangs = (4,) if indent_char != '\t' else (4, 8) |
653 valid_hangs = (indent_size,) if indent_char != '\t' \ |
|
654 else (indent_size, indent_size * 2) |
648 # remember how many brackets were opened on each line |
655 # remember how many brackets were opened on each line |
649 parens = [0] * nrows |
656 parens = [0] * nrows |
650 # relative indents of physical lines |
657 # relative indents of physical lines |
651 rel_indent = [0] * nrows |
658 rel_indent = [0] * nrows |
652 # for each depth, collect a list of opening rows |
659 # for each depth, collect a list of opening rows |
707 elif indent[depth] and start[1] < indent[depth]: |
714 elif indent[depth] and start[1] < indent[depth]: |
708 if visual_indent is not True: |
715 if visual_indent is not True: |
709 # visual indent is broken |
716 # visual indent is broken |
710 yield (start, "E128 continuation line " |
717 yield (start, "E128 continuation line " |
711 "under-indented for visual indent") |
718 "under-indented for visual indent") |
712 elif hanging_indent or (indent_next and rel_indent[row] == 8): |
719 elif hanging_indent or (indent_next and |
|
720 rel_indent[row] == 2 * indent_size): |
713 # hanging indent is verified |
721 # hanging indent is verified |
714 if close_bracket and not hang_closing: |
722 if close_bracket and not hang_closing: |
715 yield (start, "E123 closing bracket does not match " |
723 yield (start, "E123 closing bracket does not match " |
716 "indentation of opening bracket's line") |
724 "indentation of opening bracket's line") |
717 hangs[depth] = hang |
725 hangs[depth] = hang |
730 error = "E127", "over-indented for visual indent" |
738 error = "E127", "over-indented for visual indent" |
731 elif not close_bracket and hangs[depth]: |
739 elif not close_bracket and hangs[depth]: |
732 error = "E131", "unaligned for hanging indent" |
740 error = "E131", "unaligned for hanging indent" |
733 else: |
741 else: |
734 hangs[depth] = hang |
742 hangs[depth] = hang |
735 if hang > 4: |
743 if hang > indent_size: |
736 error = "E126", "over-indented for hanging indent" |
744 error = "E126", "over-indented for hanging indent" |
737 else: |
745 else: |
738 error = "E121", "under-indented for hanging indent" |
746 error = "E121", "under-indented for hanging indent" |
739 yield start, "%s continuation line %s" % error |
747 yield start, "%s continuation line %s" % error |
740 |
748 |
797 |
805 |
798 last_token_multiline = (start[0] != end[0]) |
806 last_token_multiline = (start[0] != end[0]) |
799 if last_token_multiline: |
807 if last_token_multiline: |
800 rel_indent[end[0] - first_row] = rel_indent[row] |
808 rel_indent[end[0] - first_row] = rel_indent[row] |
801 |
809 |
802 if indent_next and expand_indent(line) == indent_level + 4: |
810 if indent_next and expand_indent(line) == indent_level + indent_size: |
803 pos = (start[0], indent[0] + 4) |
811 pos = (start[0], indent[0] + indent_size) |
804 if visual_indent: |
812 if visual_indent: |
805 code = "E129 visually indented line" |
813 code = "E129 visually indented line" |
806 else: |
814 else: |
807 code = "E125 continuation line" |
815 code = "E125 continuation line" |
808 yield pos, "%s with same indent as next logical line" % code |
816 yield pos, "%s with same indent as next logical line" % code |
1130 |
1138 |
1131 Okay: import os |
1139 Okay: import os |
1132 Okay: # this is a comment\nimport os |
1140 Okay: # this is a comment\nimport os |
1133 Okay: '''this is a module docstring'''\nimport os |
1141 Okay: '''this is a module docstring'''\nimport os |
1134 Okay: r'''this is a module docstring'''\nimport os |
1142 Okay: r'''this is a module docstring'''\nimport os |
1135 Okay: |
1143 Okay: |
1136 try:\n\timport x\nexcept ImportError:\n\tpass\nelse:\n\tpass\nimport y |
1144 try:\n\timport x\nexcept ImportError:\n\tpass\nelse:\n\tpass\nimport y |
1137 Okay: |
1145 Okay: |
1138 try:\n\timport x\nexcept ImportError:\n\tpass\nfinally:\n\tpass\nimport y |
1146 try:\n\timport x\nexcept ImportError:\n\tpass\nfinally:\n\tpass\nimport y |
1139 E402: a=1\nimport os |
1147 E402: a=1\nimport os |
1140 E402: 'One string'\n"Two string"\nimport os |
1148 E402: 'One string'\n"Two string"\nimport os |
1141 E402: a=1\nfrom sys import x |
1149 E402: a=1\nfrom sys import x |
1142 |
1150 |
1827 else: |
1836 else: |
1828 # Python 3 |
1837 # Python 3 |
1829 def readlines(filename): |
1838 def readlines(filename): |
1830 """Read the source code.""" |
1839 """Read the source code.""" |
1831 try: |
1840 try: |
1832 with open(filename, 'rb') as f: |
1841 with tokenize.open(filename) as f: |
1833 (coding, lines) = tokenize.detect_encoding(f.readline) |
1842 return f.readlines() |
1834 f = TextIOWrapper(f, coding, line_buffering=True) |
|
1835 return [line.decode(coding) for line in lines] + f.readlines() |
|
1836 except (LookupError, SyntaxError, UnicodeError): |
1843 except (LookupError, SyntaxError, UnicodeError): |
1837 # Fall back if file encoding is improperly declared |
1844 # Fall back if file encoding is improperly declared |
1838 with open(filename, encoding='latin-1') as f: |
1845 with open(filename, encoding='latin-1') as f: |
1839 return f.readlines() |
1846 return f.readlines() |
1840 isidentifier = str.isidentifier |
1847 isidentifier = str.isidentifier |
1981 self._physical_checks = options.physical_checks |
1988 self._physical_checks = options.physical_checks |
1982 self._logical_checks = options.logical_checks |
1989 self._logical_checks = options.logical_checks |
1983 self._ast_checks = options.ast_checks |
1990 self._ast_checks = options.ast_checks |
1984 self.max_line_length = options.max_line_length |
1991 self.max_line_length = options.max_line_length |
1985 self.max_doc_length = options.max_doc_length |
1992 self.max_doc_length = options.max_doc_length |
|
1993 self.indent_size = options.indent_size |
1986 self.multiline = False # in a multiline string? |
1994 self.multiline = False # in a multiline string? |
1987 self.hang_closing = options.hang_closing |
1995 self.hang_closing = options.hang_closing |
|
1996 self.indent_size = options.indent_size |
|
1997 self.indent_size_str = ({2: 'two', 4: 'four', 8: 'eight'} |
|
1998 .get(self.indent_size, str(self.indent_size))) |
1988 self.verbose = options.verbose |
1999 self.verbose = options.verbose |
1989 self.filename = filename |
2000 self.filename = filename |
1990 # Dictionary where a checker can store its custom state. |
2001 # Dictionary where a checker can store its custom state. |
1991 self._checker_states = {} |
2002 self._checker_states = {} |
1992 if filename is None: |
2003 if filename is None: |
2157 """Tokenize file, run physical line checks and yield tokens.""" |
2168 """Tokenize file, run physical line checks and yield tokens.""" |
2158 if self._io_error: |
2169 if self._io_error: |
2159 self.report_error_args(1, 0, 'E902', self._io_error, readlines) |
2170 self.report_error_args(1, 0, 'E902', self._io_error, readlines) |
2160 tokengen = tokenize.generate_tokens(self.readline) |
2171 tokengen = tokenize.generate_tokens(self.readline) |
2161 try: |
2172 try: |
|
2173 prev_physical = '' |
2162 for token in tokengen: |
2174 for token in tokengen: |
2163 if token[2][0] > self.total_lines: |
2175 if token[2][0] > self.total_lines: |
2164 return |
2176 return |
2165 self.noqa = token[4] and noqa(token[4]) |
2177 self.noqa = token[4] and noqa(token[4]) |
2166 self.maybe_check_physical(token) |
2178 self.maybe_check_physical(token, prev_physical) |
2167 yield token |
2179 yield token |
|
2180 prev_physical = token[4] |
2168 except (SyntaxError, tokenize.TokenError): |
2181 except (SyntaxError, tokenize.TokenError): |
2169 self.report_invalid_syntax() |
2182 self.report_invalid_syntax() |
2170 |
2183 |
2171 def maybe_check_physical(self, token): |
2184 def maybe_check_physical(self, token, prev_physical): |
2172 """If appropriate for token, check current physical line(s).""" |
2185 """If appropriate for token, check current physical line(s).""" |
2173 # Called after every token, but act only on end of line. |
2186 # Called after every token, but act only on end of line. |
|
2187 |
|
2188 # a newline token ends a single physical line. |
2174 if _is_eol_token(token): |
2189 if _is_eol_token(token): |
2175 # Obviously, a newline token ends a single physical line. |
2190 # if the file does not end with a newline, the NEWLINE |
2176 self.check_physical(token[4]) |
2191 # token is inserted by the parser, but it does not contain |
|
2192 # the previous physical line in `token[4]` |
|
2193 if token[4] == '': |
|
2194 self.check_physical(prev_physical) |
|
2195 else: |
|
2196 self.check_physical(token[4]) |
2177 elif token[0] == tokenize.STRING and '\n' in token[1]: |
2197 elif token[0] == tokenize.STRING and '\n' in token[1]: |
2178 # Less obviously, a string that contains newlines is a |
2198 # Less obviously, a string that contains newlines is a |
2179 # multiline string, either triple-quoted or with internal |
2199 # multiline string, either triple-quoted or with internal |
2180 # newlines backslash-escaped. Check every physical line in |
2200 # newlines backslash-escaped. Check every physical line in |
2181 # the string *except* for the last one: its newline is |
2201 # the string *except* for the last one: its newline is |
2364 |
2384 |
2365 class StandardReport(BaseReport): |
2385 class StandardReport(BaseReport): |
2366 """Collect and print the results of the checks.""" |
2386 """Collect and print the results of the checks.""" |
2367 |
2387 |
2368 def __init__(self, options): |
2388 def __init__(self, options): |
2369 super(StandardReport, self).__init__(options) |
2389 super().__init__(options) |
2370 self._fmt = REPORT_FORMAT.get(options.format.lower(), |
2390 self._fmt = REPORT_FORMAT.get(options.format.lower(), |
2371 options.format) |
2391 options.format) |
2372 self._repeat = options.repeat |
2392 self._repeat = options.repeat |
2373 self._show_source = options.show_source |
2393 self._show_source = options.show_source |
2374 self._show_pep8 = options.show_pep8 |
2394 self._show_pep8 = options.show_pep8 |
2375 |
2395 |
2376 def init_file(self, filename, lines, expected, line_offset): |
2396 def init_file(self, filename, lines, expected, line_offset): |
2377 """Signal a new file.""" |
2397 """Signal a new file.""" |
2378 self._deferred_print = [] |
2398 self._deferred_print = [] |
2379 return super(StandardReport, self).init_file( |
2399 return super().init_file( |
2380 filename, lines, expected, line_offset) |
2400 filename, lines, expected, line_offset) |
2381 |
2401 |
2382 def error(self, line_number, offset, text, check): |
2402 def error(self, line_number, offset, text, check): |
2383 """Report an error, according to options.""" |
2403 """Report an error, according to options.""" |
2384 code = super(StandardReport, self).error(line_number, offset, |
2404 code = super().error(line_number, offset, |
2385 text, check) |
2405 text, check) |
2386 if code and (self.counters[code] == 1 or self._repeat): |
2406 if code and (self.counters[code] == 1 or self._repeat): |
2387 self._deferred_print.append( |
2407 self._deferred_print.append( |
2388 (line_number, offset, code, text[5:], check.__doc__)) |
2408 (line_number, offset, code, text[5:], check.__doc__)) |
2389 return code |
2409 return code |
2390 |
2410 |
2391 def error_args(self, line_number, offset, code, check, *args): |
2411 def error_args(self, line_number, offset, code, check, *args): |
2392 """Report an error, according to options.""" |
2412 """Report an error, according to options.""" |
2393 code = super(StandardReport, self).error_args(line_number, offset, |
2413 code = super().error_args(line_number, offset, |
2394 code, check, *args) |
2414 code, check, *args) |
2395 if code and (self.counters[code] == 1 or self._repeat): |
2415 if code and (self.counters[code] == 1 or self._repeat): |
2396 self._deferred_print.append( |
2416 self._deferred_print.append( |
2397 (line_number, offset, code, args, check.__doc__)) |
2417 (line_number, offset, code, args, check.__doc__)) |
2398 return code |
2418 return code |
2428 |
2448 |
2429 class DiffReport(StandardReport): |
2449 class DiffReport(StandardReport): |
2430 """Collect and print the results for the changed lines only.""" |
2450 """Collect and print the results for the changed lines only.""" |
2431 |
2451 |
2432 def __init__(self, options): |
2452 def __init__(self, options): |
2433 super(DiffReport, self).__init__(options) |
2453 super().__init__(options) |
2434 self._selected = options.selected_lines |
2454 self._selected = options.selected_lines |
2435 |
2455 |
2436 def error(self, line_number, offset, text, check): |
2456 def error(self, line_number, offset, text, check): |
2437 if line_number not in self._selected[self.filename]: |
2457 if line_number not in self._selected[self.filename]: |
2438 return |
2458 return |
2439 return super(DiffReport, self).error(line_number, offset, text, check) |
2459 return super().error(line_number, offset, text, check) |
2440 |
2460 |
2441 |
2461 |
2442 class StyleGuide(object): |
2462 class StyleGuide(object): |
2443 """Initialize a PEP-8 instance with few options.""" |
2463 """Initialize a PEP-8 instance with few options.""" |
2444 |
2464 |
2582 """Create the parser for the program.""" |
2602 """Create the parser for the program.""" |
2583 parser = OptionParser(prog=prog, version=version, |
2603 parser = OptionParser(prog=prog, version=version, |
2584 usage="%prog [options] input ...") |
2604 usage="%prog [options] input ...") |
2585 parser.config_options = [ |
2605 parser.config_options = [ |
2586 'exclude', 'filename', 'select', 'ignore', 'max-line-length', |
2606 'exclude', 'filename', 'select', 'ignore', 'max-line-length', |
2587 'max-doc-length', 'hang-closing', 'count', 'format', 'quiet', |
2607 'max-doc-length', 'indent-size', 'hang-closing', 'count', 'format', |
2588 'show-pep8', 'show-source', 'statistics', 'verbose'] |
2608 'quiet', 'show-pep8', 'show-source', 'statistics', 'verbose'] |
2589 parser.add_option('-v', '--verbose', default=0, action='count', |
2609 parser.add_option('-v', '--verbose', default=0, action='count', |
2590 help="print status messages, or debug with -vv") |
2610 help="print status messages, or debug with -vv") |
2591 parser.add_option('-q', '--quiet', default=0, action='count', |
2611 parser.add_option('-q', '--quiet', default=0, action='count', |
2592 help="report only file names, or nothing with -qq") |
2612 help="report only file names, or nothing with -qq") |
2593 parser.add_option('-r', '--repeat', default=True, action='store_true', |
2613 parser.add_option('-r', '--repeat', default=True, action='store_true', |
2623 "(default: %default)") |
2643 "(default: %default)") |
2624 parser.add_option('--max-doc-length', type='int', metavar='n', |
2644 parser.add_option('--max-doc-length', type='int', metavar='n', |
2625 default=None, |
2645 default=None, |
2626 help="set maximum allowed doc line length and perform " |
2646 help="set maximum allowed doc line length and perform " |
2627 "these checks (unchecked if not set)") |
2647 "these checks (unchecked if not set)") |
|
2648 parser.add_option('--indent-size', type='int', metavar='n', |
|
2649 default=INDENT_SIZE, |
|
2650 help="set how many spaces make up an indent " |
|
2651 "(default: %default)") |
2628 parser.add_option('--hang-closing', action='store_true', |
2652 parser.add_option('--hang-closing', action='store_true', |
2629 help="hang closing bracket instead of matching " |
2653 help="hang closing bracket instead of matching " |
2630 "indentation of opening bracket's line") |
2654 "indentation of opening bracket's line") |
2631 parser.add_option('--format', metavar='format', default='default', |
2655 parser.add_option('--format', metavar='format', default='default', |
2632 help="set the error format [default|pylint|<custom>]") |
2656 help="set the error format [default|pylint|<custom>]") |