28 Check Python source code formatting, according to PEP 8. 30 For usage and a list of options, try this: 33 This program and its regression test suite live here: 34 http://github.com/jcrocholl/pep8 36 Groups of errors and warnings: 48 from __future__
import with_statement
57 from optparse
import OptionParser
58 from fnmatch
import fnmatch
60 from configparser
import RawConfigParser
61 from io
import TextIOWrapper
63 from ConfigParser
import RawConfigParser
67 DEFAULT_EXCLUDE =
'.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' 68 DEFAULT_IGNORE =
'E121,E123,E126,E226,E24,E704' 70 if sys.platform ==
'win32':
71 USER_CONFIG = os.path.expanduser(
r'~\.pep8')
73 USER_CONFIG = os.path.join(
74 os.getenv(
'XDG_CONFIG_HOME')
or os.path.expanduser(
'~/.config'),
80 PROJECT_CONFIG = (
'setup.cfg',
'tox.ini',
'.pep8')
81 TESTSUITE_PATH = os.path.join(os.path.dirname(__file__),
'testsuite')
84 'default':
'%(path)s:%(row)d:%(col)d: %(code)s %(text)s',
85 'pylint':
'%(path)s:%(row)d: [%(code)s] %(text)s',
89 SINGLETONS = frozenset([
'False',
'None',
'True'])
90 KEYWORDS = frozenset(keyword.kwlist + [
'print']) - SINGLETONS
91 UNARY_OPERATORS = frozenset([
'>>',
'**',
'*',
'+',
'-'])
92 ARITHMETIC_OP = frozenset([
'**',
'*',
'/',
'//',
'+',
'-'])
93 WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union([
'^',
'&',
'|',
'<<',
'>>',
'%'])
94 WS_NEEDED_OPERATORS = frozenset([
95 '**=',
'*=',
'/=',
'//=',
'+=',
'-=',
'!=',
'<>',
'<',
'>',
96 '%=',
'^=',
'&=',
'|=',
'==',
'<=',
'>=',
'<<=',
'>>=',
'='])
97 WHITESPACE = frozenset(
' \t')
98 NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE])
99 SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT])
101 SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN])
102 BENCHMARK_KEYS = [
'directories',
'files',
'logical lines',
'physical lines']
104 INDENT_REGEX = re.compile(
r'([ \t]*)')
105 RAISE_COMMA_REGEX = re.compile(
r'raise\s+\w+\s*,')
106 RERAISE_COMMA_REGEX = re.compile(
r'raise\s+\w+\s*,.*,\s*\w+\s*$')
107 ERRORCODE_REGEX = re.compile(
r'\b[A-Z]\d{3}\b')
108 DOCSTRING_REGEX = re.compile(
r'u?r?["\']')
109 EXTRANEOUS_WHITESPACE_REGEX = re.compile(
r'[[({] | []}),;:]')
110 WHITESPACE_AFTER_COMMA_REGEX = re.compile(
r'[,;:]\s*(?: |\t)')
111 COMPARE_SINGLETON_REGEX = re.compile(
r'\b(None|False|True)?\s*([=!]=)' 112 r'\s*(?(1)|(None|False|True))\b')
113 COMPARE_NEGATIVE_REGEX = re.compile(
r'\b(not)\s+[^][)(}{ ]+\s+(in|is)\s')
114 COMPARE_TYPE_REGEX = re.compile(
r'(?:[=!]=|is(?:\s+not)?)\s*type(?:s.\w+Type' 115 r'|\s*\(\s*([^)]*[^ )])\s*\))')
116 KEYWORD_REGEX = re.compile(
r'(\s*)\b(?:%s)\b(\s*)' %
r'|'.join(KEYWORDS))
117 OPERATOR_REGEX = re.compile(
r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)')
118 LAMBDA_REGEX = re.compile(
r'\blambda\b')
119 HUNK_REGEX = re.compile(
r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$')
123 COMMENT_WITH_NL = tokenize.generate_tokens([
'#\n'].pop).send(
None)[1] ==
'#\n' 132 r"""Never mix tabs and spaces. 134 The most popular way of indenting Python is with spaces only. The 135 second-most popular way is with tabs only. Code indented with a mixture 136 of tabs and spaces should be converted to using spaces exclusively. When 137 invoking the Python command line interpreter with the -t option, it issues 138 warnings about code that illegally mixes tabs and spaces. When using -tt 139 these warnings become errors. These options are highly recommended! 141 Okay: if a == 0:\n a = 1\n b = 1 142 E101: if a == 0:\n a = 1\n\tb = 1 144 indent = INDENT_REGEX.match(physical_line).group(1)
145 for offset, char
in enumerate(indent):
146 if char != indent_char:
147 return offset,
"E101 indentation contains mixed spaces and tabs" 151 r"""For new projects, spaces-only are strongly recommended over tabs. 153 Okay: if True:\n return 154 W191: if True:\n\treturn 156 indent = INDENT_REGEX.match(physical_line).group(1)
158 return indent.index(
'\t'),
"W191 indentation contains tabs" 162 r"""Trailing whitespace is superfluous. 164 The warning returned varies on whether the line itself is blank, for easier 165 filtering for those who want to indent their blank lines. 169 W293: class Foo(object):\n \n bang = 12 171 physical_line = physical_line.rstrip(
'\n')
172 physical_line = physical_line.rstrip(
'\r')
173 physical_line = physical_line.rstrip(
'\x0c')
174 stripped = physical_line.rstrip(
' \t\v')
175 if physical_line != stripped:
177 return len(stripped),
"W291 trailing whitespace" 179 return 0,
"W293 blank line contains whitespace" 183 r"""Trailing blank lines are superfluous. 188 However the last line should end with a new line (warning W292). 190 if line_number == total_lines:
191 stripped_last_line = physical_line.rstrip()
192 if not stripped_last_line:
193 return 0,
"W391 blank line at end of file" 194 if stripped_last_line == physical_line:
195 return len(physical_line),
"W292 no newline at end of file" 199 r"""Limit all lines to a maximum of 79 characters. 201 There are still many devices around that are limited to 80 character 202 lines; plus, limiting windows to 80 characters makes it possible to have 203 several windows side-by-side. The default wrapping on such devices looks 204 ugly. Therefore, please limit all lines to a maximum of 79 characters. 205 For flowing long blocks of text (docstrings or comments), limiting the 206 length to 72 characters is recommended. 210 line = physical_line.rstrip()
212 if length > max_line_length
and not noqa(line):
215 chunks = line.split()
216 if ((len(chunks) == 1
and multiline)
or 217 (len(chunks) == 2
and chunks[0] ==
'#'))
and \
218 len(line) - len(chunks[-1]) < max_line_length - 7:
220 if hasattr(line,
'decode'):
223 length = len(line.decode(
'utf-8'))
226 if length > max_line_length:
227 return (max_line_length,
"E501 line too long " 228 "(%d > %d characters)" % (length, max_line_length))
236 def blank_lines(logical_line, blank_lines, indent_level, line_number,
237 blank_before, previous_logical, previous_indent_level):
238 r"""Separate top-level function and class definitions with two blank lines. 240 Method definitions inside a class are separated by a single blank line. 242 Extra blank lines may be used (sparingly) to separate groups of related 243 functions. Blank lines may be omitted between a bunch of related 244 one-liners (e.g. a set of dummy implementations). 246 Use blank lines in functions, sparingly, to indicate logical sections. 248 Okay: def a():\n pass\n\n\ndef b():\n pass 249 Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass 251 E301: class Foo:\n b = 0\n def bar():\n pass 252 E302: def a():\n pass\n\ndef b(n):\n pass 253 E303: def a():\n pass\n\n\n\ndef b(n):\n pass 254 E303: def a():\n\n\n\n pass 255 E304: @decorator\n\ndef a():\n pass 257 if line_number < 3
and not previous_logical:
259 if previous_logical.startswith(
'@'):
261 yield 0,
"E304 blank lines found after function decorator" 262 elif blank_lines > 2
or (indent_level
and blank_lines == 2):
263 yield 0,
"E303 too many blank lines (%d)" % blank_lines
264 elif logical_line.startswith((
'def ',
'class ',
'@')):
266 if not (blank_before
or previous_indent_level < indent_level
or 267 DOCSTRING_REGEX.match(previous_logical)):
268 yield 0,
"E301 expected 1 blank line, found 0" 269 elif blank_before != 2:
270 yield 0,
"E302 expected 2 blank lines, found %d" % blank_before
274 r"""Avoid extraneous whitespace. 276 Avoid extraneous whitespace in these situations: 277 - Immediately inside parentheses, brackets or braces. 278 - Immediately before a comma, semicolon, or colon. 280 Okay: spam(ham[1], {eggs: 2}) 281 E201: spam( ham[1], {eggs: 2}) 282 E201: spam(ham[ 1], {eggs: 2}) 283 E201: spam(ham[1], { eggs: 2}) 284 E202: spam(ham[1], {eggs: 2} ) 285 E202: spam(ham[1 ], {eggs: 2}) 286 E202: spam(ham[1], {eggs: 2 }) 288 E203: if x == 4: print x, y; x, y = y , x 289 E203: if x == 4: print x, y ; x, y = y, x 290 E203: if x == 4 : print x, y; x, y = y, x 293 for match
in EXTRANEOUS_WHITESPACE_REGEX.finditer(line):
296 found = match.start()
297 if text == char +
' ':
299 yield found + 1,
"E201 whitespace after '%s'" % char
300 elif line[found - 1] !=
',':
301 code = (
'E202' if char
in '}])' else 'E203')
302 yield found,
"%s whitespace before '%s'" % (code, char)
306 r"""Avoid extraneous whitespace around keywords. 311 E273: True and\tFalse 312 E274: True\tand False 314 for match
in KEYWORD_REGEX.finditer(logical_line):
315 before, after = match.groups()
318 yield match.start(1),
"E274 tab before keyword" 319 elif len(before) > 1:
320 yield match.start(1),
"E272 multiple spaces before keyword" 323 yield match.start(2),
"E273 tab after keyword" 325 yield match.start(2),
"E271 multiple spaces after keyword" 329 r"""Each comma, semicolon or colon should be followed by whitespace. 342 for index
in range(len(line) - 1):
344 if char
in ',;:' and line[index + 1]
not in WHITESPACE:
345 before = line[:index]
346 if char ==
':' and before.count(
'[') > before.count(
']')
and \
347 before.rfind(
'{') < before.rfind(
'['):
349 if char ==
',' and line[index + 1] ==
')':
351 yield index,
"E231 missing whitespace after '%s'" % char
354 def indentation(logical_line, previous_logical, indent_char,
355 indent_level, previous_indent_level):
356 r"""Use 4 spaces per indentation level. 358 For really old code that you don't want to mess up, you can continue to 362 Okay: if a == 0:\n a = 1 366 Okay: for item in items:\n pass 367 E112: for item in items:\npass 368 E115: for item in items:\n# Hi\n pass 372 E116: a = 1\n # b = 2 374 c = 0
if logical_line
else 3
375 tmpl =
"E11%d %s" if logical_line
else "E11%d %s (comment)" 377 yield 0, tmpl % (1 + c,
"indentation is not a multiple of four")
378 indent_expect = previous_logical.endswith(
':')
379 if indent_expect
and indent_level <= previous_indent_level:
380 yield 0, tmpl % (2 + c,
"expected an indented block")
381 elif not indent_expect
and indent_level > previous_indent_level:
382 yield 0, tmpl % (3 + c,
"unexpected indentation")
386 indent_char, noqa, verbose):
387 r"""Continuation lines indentation. 389 Continuation lines should align wrapped elements either vertically 390 using Python's implicit line joining inside parentheses, brackets 391 and braces, or using a hanging indent. 393 When using a hanging indent these considerations should be applied: 394 - there should be no arguments on the first line, and 395 - further indentation should be used to clearly distinguish itself as a 405 E124: a = (24,\n 42\n) 406 E125: if (\n b):\n pass 410 E129: if (a or\n b):\n pass 411 E131: a = (\n 42\n 24) 413 first_row = tokens[0][2][0]
414 nrows = 1 + tokens[-1][2][0] - first_row
415 if noqa
or nrows == 1:
422 indent_next = logical_line.endswith(
':')
425 valid_hangs = (4,)
if indent_char !=
'\t' else (4, 8)
429 rel_indent = [0] * nrows
436 last_indent = tokens[0][2]
438 last_token_multiline =
False 440 indent = [last_indent[1]]
442 print(
">>> " + tokens[0][4].rstrip())
444 for token_type, text, start, end, line
in tokens:
446 newline = row < start[0] - first_row
448 row = start[0] - first_row
449 newline =
not last_token_multiline
and token_type
not in NEWLINE
455 print(
"... " + line.rstrip())
461 close_bracket = (token_type == tokenize.OP
and text
in ']})')
464 for open_row
in reversed(open_rows[depth]):
465 hang = rel_indent[row] - rel_indent[open_row]
466 hanging_indent = hang
in valid_hangs
470 hanging_indent = (hang == hangs[depth])
472 visual_indent = (
not close_bracket
and hang > 0
and 473 indent_chances.get(start[1]))
475 if close_bracket
and indent[depth]:
477 if start[1] != indent[depth]:
478 yield (start,
"E124 closing bracket does not match " 479 "visual indentation")
480 elif close_bracket
and not hang:
483 yield start,
"E133 closing bracket is missing indentation" 484 elif indent[depth]
and start[1] < indent[depth]:
485 if visual_indent
is not True:
487 yield (start,
"E128 continuation line " 488 "under-indented for visual indent")
489 elif hanging_indent
or (indent_next
and rel_indent[row] == 8):
491 if close_bracket
and not hang_closing:
492 yield (start,
"E123 closing bracket does not match " 493 "indentation of opening bracket's line")
495 elif visual_indent
is True:
497 indent[depth] = start[1]
498 elif visual_indent
in (text, str):
504 error =
"E122",
"missing indentation or outdented" 506 error =
"E127",
"over-indented for visual indent" 507 elif not close_bracket
and hangs[depth]:
508 error =
"E131",
"unaligned for hanging indent" 512 error =
"E126",
"over-indented for hanging indent" 514 error =
"E121",
"under-indented for hanging indent" 515 yield start,
"%s continuation line %s" % error
519 token_type
not in (tokenize.NL, tokenize.COMMENT)
and 521 indent[depth] = start[1]
522 indent_chances[start[1]] =
True 524 print(
"bracket depth %s indent to %s" % (depth, start[1]))
526 elif (token_type
in (tokenize.STRING, tokenize.COMMENT)
or 527 text
in (
'u', 'ur', 'b', 'br')):
528 indent_chances[start[1]] = str
530 elif not indent_chances
and not row
and not depth
and text ==
'if':
531 indent_chances[end[1] + 1] =
True 532 elif text ==
':' and line[end[1]:].isspace():
533 open_rows[depth].append(row)
536 if token_type == tokenize.OP:
541 if len(open_rows) == depth:
543 open_rows[depth].append(row)
546 print(
"bracket depth %s seen, col %s, visual min = %s" %
547 (depth, start[1], indent[depth]))
548 elif text
in ')]}' and depth > 0:
550 prev_indent = indent.pop()
or last_indent[1]
552 for d
in range(depth):
553 if indent[d] > prev_indent:
555 for ind
in list(indent_chances):
556 if ind >= prev_indent:
557 del indent_chances[ind]
558 del open_rows[depth + 1:]
561 indent_chances[indent[depth]] =
True 562 for idx
in range(row, -1, -1):
566 assert len(indent) == depth + 1
567 if start[1]
not in indent_chances:
569 indent_chances[start[1]] = text
571 last_token_multiline = (start[0] != end[0])
572 if last_token_multiline:
573 rel_indent[end[0] - first_row] = rel_indent[row]
576 pos = (start[0], indent[0] + 4)
578 code =
"E129 visually indented line" 580 code =
"E125 continuation line" 581 yield pos,
"%s with same indent as next logical line" % code
585 r"""Avoid extraneous whitespace. 587 Avoid extraneous whitespace in the following situations: 588 - before the open parenthesis that starts the argument list of a 590 - before the open parenthesis that starts an indexing or slicing. 595 Okay: dict['key'] = list[index] 596 E211: dict ['key'] = list[index] 597 E211: dict['key'] = list [index] 599 prev_type, prev_text, __, prev_end, __ = tokens[0]
600 for index
in range(1, len(tokens)):
601 token_type, text, start, end, __ = tokens[index]
602 if (token_type == tokenize.OP
and 604 start != prev_end
and 605 (prev_type == tokenize.NAME
or prev_text
in '}])')
and 607 (index < 2
or tokens[index - 2][1] !=
'class')
and 609 not keyword.iskeyword(prev_text)):
610 yield prev_end,
"E211 whitespace before '%s'" % text
611 prev_type = token_type
617 r"""Avoid extraneous whitespace around an operator. 625 for match
in OPERATOR_REGEX.finditer(logical_line):
626 before, after = match.groups()
629 yield match.start(1),
"E223 tab before operator" 630 elif len(before) > 1:
631 yield match.start(1),
"E221 multiple spaces before operator" 634 yield match.start(2),
"E224 tab after operator" 636 yield match.start(2),
"E222 multiple spaces after operator" 640 r"""Surround operators with a single space on either side. 642 - Always surround these binary operators with a single space on 643 either side: assignment (=), augmented assignment (+=, -= etc.), 644 comparisons (==, <, >, !=, <=, >=, in, not in, is, is not), 645 Booleans (and, or, not). 647 - If operators with different priorities are used, consider adding 648 whitespace around the operators with the lowest priorities. 653 Okay: hypot2 = x * x + y * y 654 Okay: c = (a + b) * (a - b) 655 Okay: foo(bar, key='word', *args, **kwargs) 662 E226: c = (a+b) * (a-b) 663 E226: hypot2 = x*x + y*y 665 E228: msg = fmt%(errno, errmsg) 669 prev_type = tokenize.OP
670 prev_text = prev_end =
None 671 for token_type, text, start, end, line
in tokens:
672 if token_type
in SKIP_COMMENTS:
674 if text
in (
'(',
'lambda'):
679 if start != prev_end:
681 if need_space
is not True and not need_space[1]:
682 yield (need_space[0],
683 "E225 missing whitespace around operator")
685 elif text ==
'>' and prev_text
in (
'<',
'-'):
690 if need_space
is True or need_space[1]:
692 yield prev_end,
"E225 missing whitespace around operator" 693 elif prev_text !=
'**':
694 code, optype =
'E226',
'arithmetic' 696 code, optype =
'E228',
'modulo' 697 elif prev_text
not in ARITHMETIC_OP:
698 code, optype =
'E227',
'bitwise or shift' 699 yield (need_space[0],
"%s missing whitespace " 700 "around %s operator" % (code, optype))
702 elif token_type == tokenize.OP
and prev_end
is not None:
703 if text ==
'=' and parens:
706 elif text
in WS_NEEDED_OPERATORS:
708 elif text
in UNARY_OPERATORS:
712 if (prev_text
in '}])' if prev_type == tokenize.OP
713 else prev_text
not in KEYWORDS):
715 elif text
in WS_OPTIONAL_OPERATORS:
718 if need_space
is None:
721 need_space = (prev_end, start != prev_end)
722 elif need_space
and start == prev_end:
724 yield prev_end,
"E225 missing whitespace around operator" 726 prev_type = token_type
732 r"""Avoid extraneous whitespace after a comma or a colon. 734 Note: these checks are disabled by default 741 for m
in WHITESPACE_AFTER_COMMA_REGEX.finditer(line):
742 found = m.start() + 1
743 if '\t' in m.group():
744 yield found,
"E242 tab after '%s'" % m.group()[0]
746 yield found,
"E241 multiple spaces after '%s'" % m.group()[0]
750 r"""Don't use spaces around the '=' sign in function arguments. 752 Don't use spaces around the '=' sign when used to indicate a 753 keyword argument or a default parameter value. 755 Okay: def complex(real, imag=0.0): 756 Okay: return magic(r=real, i=imag) 757 Okay: boolean(a == b) 758 Okay: boolean(a != b) 759 Okay: boolean(a <= b) 760 Okay: boolean(a >= b) 761 Okay: def foo(arg: int = 42): 763 E251: def complex(real, imag = 0.0): 764 E251: return magic(r = real, i = imag) 769 annotated_func_arg =
False 770 in_def = logical_line.startswith(
'def')
771 message =
"E251 unexpected spaces around keyword / parameter equals" 772 for token_type, text, start, end, line
in tokens:
773 if token_type == tokenize.NL:
777 if start != prev_end:
778 yield (prev_end, message)
779 if token_type == tokenize.OP:
784 elif in_def
and text ==
':' and parens == 1:
785 annotated_func_arg =
True 786 elif parens
and text ==
',' and parens == 1:
787 annotated_func_arg =
False 788 elif parens
and text ==
'=' and not annotated_func_arg:
790 if start != prev_end:
791 yield (prev_end, message)
793 annotated_func_arg =
False 799 r"""Separate inline comments by at least two spaces. 801 An inline comment is a comment on the same line as a statement. Inline 802 comments should be separated by at least two spaces from the statement. 803 They should start with a # and a single space. 805 Each line of a block comment starts with a # and a single space 806 (unless it is indented text inside the comment). 808 Okay: x = x + 1 # Increment x 809 Okay: x = x + 1 # Increment x 810 Okay: # Block comment 811 E261: x = x + 1 # Increment x 812 E262: x = x + 1 #Increment x 813 E262: x = x + 1 # Increment x 815 E266: ### Block comment 818 for token_type, text, start, end, line
in tokens:
819 if token_type == tokenize.COMMENT:
820 inline_comment = line[:start[1]].strip()
822 if prev_end[0] == start[0]
and start[1] < prev_end[1] + 2:
824 "E261 at least two spaces before inline comment")
825 symbol, sp, comment = text.partition(
' ')
826 bad_prefix = symbol
not in '#:' and (symbol.lstrip(
'#')[:1]
or '#')
828 if bad_prefix
or comment[:1]
in WHITESPACE:
829 yield start,
"E262 inline comment should start with '# '" 830 elif bad_prefix
and (bad_prefix !=
'!' or start[0] > 1):
831 if bad_prefix !=
'#':
832 yield start,
"E265 block comment should start with '# '" 834 yield start,
"E266 too many leading '#' for block comment" 835 elif token_type != tokenize.NL:
840 r"""Imports should usually be on separate lines. 842 Okay: import os\nimport sys 845 Okay: from subprocess import Popen, PIPE 846 Okay: from myclas import MyClass 847 Okay: from foo.bar.yourclass import YourClass 849 Okay: import foo.bar.yourclass 852 if line.startswith(
'import '):
853 found = line.find(
',')
854 if -1 < found
and ';' not in line[:found]:
855 yield found,
"E401 multiple imports on one line" 859 logical_line, indent_level, checker_state, noqa):
860 r"""Imports are always put at the top of the file, just after any module 861 comments and docstrings, and before module globals and constants. 864 Okay: # this is a comment\nimport os 865 Okay: '''this is a module docstring'''\nimport os 866 Okay: r'''this is a module docstring'''\nimport os 867 Okay: try:\n import x\nexcept:\n pass\nelse:\n pass\nimport y 868 Okay: try:\n import x\nexcept:\n pass\nfinally:\n pass\nimport y 870 E402: 'One string'\n"Two string"\nimport os 871 E402: a=1\nfrom sys import x 873 Okay: if x:\n import os 875 def is_string_literal(line):
876 if line[0]
in 'uUbB':
878 if line
and line[0]
in 'rR':
880 return line
and (line[0] ==
'"' or line[0] ==
"'")
882 allowed_try_keywords = (
'try',
'except',
'else',
'finally')
891 if line.startswith(
'import ')
or line.startswith(
'from '):
892 if checker_state.get(
'seen_non_imports',
False):
893 yield 0,
"E402 module level import not at top of file" 894 elif any(line.startswith(kw)
for kw
in allowed_try_keywords):
898 elif is_string_literal(line):
900 if checker_state.get(
'seen_docstring',
False):
901 checker_state[
'seen_non_imports'] =
True 903 checker_state[
'seen_docstring'] =
True 905 checker_state[
'seen_non_imports'] =
True 909 r"""Compound statements (on the same line) are generally discouraged. 911 While sometimes it's okay to put an if/for/while with a small body 912 on the same line, never do this for multi-clause statements. 913 Also avoid folding such long lines! 915 Always use a def statement instead of an assignment statement that 916 binds a lambda expression directly to a name. 918 Okay: if foo == 'blah':\n do_blah_thing() 923 E701: if foo == 'blah': do_blah_thing() 924 E701: for x in lst: total += x 925 E701: while t < 10: t = delay() 926 E701: if foo == 'blah': do_blah_thing() 927 E701: else: do_non_blah_thing() 928 E701: try: something() 929 E701: finally: cleanup() 930 E701: if foo == 'blah': one(); two(); three() 931 E702: do_one(); do_two(); do_three() 932 E703: do_four(); # useless semicolon 933 E704: def f(x): return 2*x 934 E731: f = lambda x: 2*x 937 last_char = len(line) - 1
938 found = line.find(
':')
939 while -1 < found < last_char:
940 before = line[:found]
941 if ((before.count(
'{') <= before.count(
'}')
and 942 before.count(
'[') <= before.count(
']')
and 943 before.count(
'(') <= before.count(
')'))):
944 lambda_kw = LAMBDA_REGEX.search(before)
946 before = line[:lambda_kw.start()].rstrip()
947 if before[-1:] ==
'=' and isidentifier(before[:-1].strip()):
948 yield 0, (
"E731 do not assign a lambda expression, use a " 951 if before.startswith(
'def '):
952 yield 0,
"E704 multiple statements on one line (def)" 954 yield found,
"E701 multiple statements on one line (colon)" 955 found = line.find(
':', found + 1)
956 found = line.find(
';')
958 if found < last_char:
959 yield found,
"E702 multiple statements on one line (semicolon)" 961 yield found,
"E703 statement ends with a semicolon" 962 found = line.find(
';', found + 1)
966 r"""Avoid explicit line join between brackets. 968 The preferred way of wrapping long lines is by using Python's implied line 969 continuation inside parentheses, brackets and braces. Long lines can be 970 broken over multiple lines by wrapping expressions in parentheses. These 971 should be used in preference to using a backslash for line continuation. 973 E502: aaa = [123, \\n 123] 974 E502: aaa = ("bbb " \\n "ccc") 976 Okay: aaa = [123,\n 123] 977 Okay: aaa = ("bbb "\n "ccc") 978 Okay: aaa = "bbb " \\n "ccc" 981 prev_start = prev_end = parens = 0
984 for token_type, text, start, end, line
in tokens:
985 if token_type == tokenize.COMMENT:
987 if start[0] != prev_start
and parens
and backslash
and not comment:
988 yield backslash,
"E502 the backslash is redundant between brackets" 989 if end[0] != prev_end:
990 if line.rstrip(
'\r\n').endswith(
'\\'):
991 backslash = (end[0], len(line.splitlines()[-1]) - 1)
994 prev_start = prev_end = end[0]
996 prev_start = start[0]
997 if token_type == tokenize.OP:
1006 Avoid breaks before binary operators. 1008 The preferred place to break around a binary operator is after the 1009 operator, not before it. 1011 W503: (width == 0\n + height == 0) 1012 W503: (width == 0\n and height == 0) 1014 Okay: (width == 0 +\n height == 0) 1017 Okay: x = '''\n''' + '' 1019 Okay: foo(x, # comment\n -y) 1021 def is_binary_operator(token_type, text):
1025 return ((token_type == tokenize.OP
or text
in [
'and',
'or'])
and 1026 text
not in "()[]{},:.;@=%")
1029 unary_context =
True 1030 for token_type, text, start, end, line
in tokens:
1031 if token_type == tokenize.COMMENT:
1033 if (
'\n' in text
or '\r' in text)
and token_type != tokenize.STRING:
1036 if (is_binary_operator(token_type, text)
and line_break
and 1038 yield start,
"W503 line break before binary operator" 1039 unary_context = text
in '([{,;' 1044 r"""Comparison to singletons should use "is" or "is not". 1046 Comparisons to singletons like None should always be done 1047 with "is" or "is not", never the equality operators. 1049 Okay: if arg is not None: 1050 E711: if arg != None: 1051 E711: if None == arg: 1052 E712: if arg == True: 1053 E712: if False == arg: 1055 Also, beware of writing if x when you really mean if x is not None -- 1056 e.g. when testing whether a variable or argument that defaults to None was 1057 set to some other value. The other value might have a type (such as a 1058 container) that could be false in a boolean context! 1060 match =
not noqa
and COMPARE_SINGLETON_REGEX.search(logical_line)
1062 singleton = match.group(1)
or match.group(3)
1063 same = (match.group(2) ==
'==')
1065 msg =
"'if cond is %s:'" % ((
'' if same
else 'not ') + singleton)
1066 if singleton
in (
'None',):
1070 nonzero = ((singleton ==
'True' and same)
or 1071 (singleton ==
'False' and not same))
1072 msg +=
" or 'if %scond:'" % (
'' if nonzero
else 'not ')
1073 yield match.start(2), (
"%s comparison to %s should be %s" %
1074 (code, singleton, msg))
1078 r"""Negative comparison should be done using "not in" and "is not". 1080 Okay: if x not in y:\n pass 1081 Okay: assert (X in Y or X is Z) 1082 Okay: if not (X in Y):\n pass 1083 Okay: zz = x is not y 1084 E713: Z = not X in Y 1085 E713: if not X.B in Y:\n pass 1086 E714: if not X is Y:\n pass 1087 E714: Z = not X.B is Y 1089 match = COMPARE_NEGATIVE_REGEX.search(logical_line)
1091 pos = match.start(1)
1092 if match.group(2) ==
'in':
1093 yield pos,
"E713 test for membership should be 'not in'" 1095 yield pos,
"E714 test for object identity should be 'is not'" 1099 r"""Object type comparisons should always use isinstance(). 1101 Do not compare types directly. 1103 Okay: if isinstance(obj, int): 1104 E721: if type(obj) is type(1): 1106 When checking if an object is a string, keep in mind that it might be a 1107 unicode string too! In Python 2.3, str and unicode have a common base 1108 class, basestring, so you can do: 1110 Okay: if isinstance(obj, basestring): 1111 Okay: if type(a1) is type(b1): 1113 match = COMPARE_TYPE_REGEX.search(logical_line)
1114 if match
and not noqa:
1115 inst = match.group(1)
1116 if inst
and isidentifier(inst)
and inst
not in SINGLETONS:
1118 yield match.start(),
"E721 do not compare types, use 'isinstance()'" 1122 r"""The {}.has_key() method is removed in Python 3: use the 'in' operator. 1124 Okay: if "alph" in d:\n print d["alph"] 1125 W601: assert d.has_key('alph') 1127 pos = logical_line.find(
'.has_key(')
1128 if pos > -1
and not noqa:
1129 yield pos,
"W601 .has_key() is deprecated, use 'in'" 1133 r"""When raising an exception, use "raise ValueError('message')". 1135 The older form is removed in Python 3. 1137 Okay: raise DummyError("Message") 1138 W602: raise DummyError, "Message" 1140 match = RAISE_COMMA_REGEX.match(logical_line)
1141 if match
and not RERAISE_COMMA_REGEX.match(logical_line):
1142 yield match.end() - 1,
"W602 deprecated form of raising exception" 1146 r"""New code should always use != instead of <>. 1148 The older syntax is removed in Python 3. 1153 pos = logical_line.find(
'<>')
1155 yield pos,
"W603 '<>' is deprecated, use '!='" 1159 r"""Backticks are removed in Python 3: use repr() instead. 1161 Okay: val = repr(1 + 2) 1164 pos = logical_line.find(
'`')
1166 yield pos,
"W604 backticks are deprecated, use 'repr()'" 1174 if '' ==
''.encode():
1177 """Read the source code.""" 1178 with open(filename,
'rU')
as f:
1179 return f.readlines()
1180 isidentifier = re.compile(
r'[a-zA-Z_]\w*$').match
1181 stdin_get_value = sys.stdin.read
1185 """Read the source code.""" 1187 with open(filename,
'rb')
as f:
1188 (coding, lines) = tokenize.detect_encoding(f.readline)
1189 f = TextIOWrapper(f, coding, line_buffering=
True)
1190 return [l.decode(coding)
for l
in lines] + f.readlines()
1191 except (LookupError, SyntaxError, UnicodeError):
1193 with open(filename, encoding=
'latin-1')
as f:
1194 return f.readlines()
1195 isidentifier = str.isidentifier
1198 return TextIOWrapper(sys.stdin.buffer, errors=
'ignore').read()
1199 noqa = re.compile(
r'# no(?:qa|pep8)\b', re.I).search
1203 r"""Return the amount of indentation. 1205 Tabs are expanded to the next multiple of 8. 1207 >>> expand_indent(' ') 1209 >>> expand_indent('\t') 1211 >>> expand_indent(' \t') 1213 >>> expand_indent(' \t') 1216 if '\t' not in line:
1217 return len(line) - len(line.lstrip())
1221 result = result // 8 * 8 + 8
1230 """Replace contents with 'xxx' to prevent syntax matching. 1232 >>> mute_string('"abc"') 1234 >>> mute_string("'''abc'''") 1236 >>> mute_string("r'abc'")
1239 # String modifiers (e.g. u or r)
1240 start = text.index(text[-1]) + 1
1243 if text[-3:] in ('"""', "'''"):
1246 return text[:start] + 'x' * (end - start) + text[end:]
1249 def parse_udiff(diff, patterns=None, parent='.'):
1250 """Return a dictionary of matching lines."""
1251 # For each file of the diff, the entry key is the filename,
1252 # and the value is a set of row numbers to consider.
1255 for line in diff.splitlines():
1260 if line[:3] == '@@ ':
1261 hunk_match = HUNK_REGEX.match(line)
1262 (row, nrows) = [int(g or '1') for g in hunk_match.groups()]
1263 rv[path].update(range(row, row + nrows))
1264 elif line[:3] == '+++':
1265 path = line[4:].split('\t', 1)[0]
1266 if path[:2] == 'b/':
1269 return dict([(os.path.join(parent, path), rows)
1270 for (path, rows) in rv.items()
1271 if rows and filename_match(path, patterns)])
1274 def normalize_paths(value, parent=os.curdir):
1275 """Parse a comma-separated list of paths.
1277 Return a list of absolute paths.
1281 if isinstance(value, list):
1284 for path in value.split(','):
1287 path = os.path.abspath(os.path.join(parent, path))
1288 paths.append(path.rstrip('/'))
1292 def filename_match(filename, patterns, default=True):
1293 """Check if patterns contains a pattern that matches filename.
1295 If patterns is unspecified, this always returns True.
1299 return any(fnmatch(filename, pattern) for pattern in patterns)
1302 def _is_eol_token(token):
1303 return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n'
1305 def _is_eol_token(token, _eol_token=_is_eol_token):
1306 return _eol_token(token) or (token[0] == tokenize.COMMENT and
1307 token[1] == token[4])
1309 ##############################################################################
1310 # Framework to run all checks
1311 ##############################################################################
1314 _checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}}
1317 def register_check(check, codes=None):
1318 """Register a new check object."""
1319 def _add_check(check, kind, codes, args):
1320 if check in _checks[kind]:
1321 _checks[kind][check][0].extend(codes or [])
1323 _checks[kind][check] = (codes or [''], args)
1324 if inspect.isfunction(check):
1325 args = inspect.getargspec(check)[0]
1326 if args and args[0] in ('physical_line', 'logical_line'):
1328 codes = ERRORCODE_REGEX.findall(check.__doc__ or '')
1329 _add_check(check, args[0], codes, args)
1330 elif inspect.isclass(check):
1331 if inspect.getargspec(check.__init__)[0][:2] == ['self', 'tree']:
1332 _add_check(check, 'tree', codes, None)
1335 def init_checks_registry():
1336 """Register all globally visible functions.
1338 The first argument name is either 'physical_line' or 'logical_line'.
1340 mod = inspect.getmodule(register_check)
1341 for (name, function) in inspect.getmembers(mod, inspect.isfunction):
1342 register_check(function)
1343 init_checks_registry()
1346 class Checker(object):
1347 """Load a Python source file, tokenize it, check coding style."""
1349 def __init__(self, filename=None, lines=None,
1350 options=None, report=None, **kwargs):
1352 options = StyleGuide(kwargs).options
1355 self._io_error = None
1356 self._physical_checks = options.physical_checks
1357 self._logical_checks = options.logical_checks
1358 self._ast_checks = options.ast_checks
1359 self.max_line_length = options.max_line_length
1360 self.multiline = False # in a multiline string?
1361 self.hang_closing = options.hang_closing
1362 self.verbose = options.verbose
1363 self.filename = filename
1364 # Dictionary where a checker can store its custom state.
1365 self._checker_states = {}
1366 if filename is None:
1367 self.filename = 'stdin'
1368 self.lines = lines or []
1369 elif filename == '-':
1370 self.filename = 'stdin'
1371 self.lines = stdin_get_value().splitlines(True)
1374 self.lines = readlines(filename)
1376 (exc_type, exc) = sys.exc_info()[:2]
1377 self._io_error = '%s: %s' % (exc_type.__name__, exc)
1382 ord0 = ord(self.lines[0][0])
1383 if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM
1385 self.lines[0] = self.lines[0][1:]
1386 elif self.lines[0][:3] == '\xef\xbb\xbf':
1387 self.lines[0] = self.lines[0][3:]
1388 self.report = report or options.report
1389 self.report_error = self.report.error
1391 def report_invalid_syntax(self):
1392 """Check if the syntax is valid."""
1393 (exc_type, exc) = sys.exc_info()[:2]
1394 if len(exc.args) > 1:
1395 offset = exc.args[1]
1397 offset = offset[1:3]
1400 self.report_error(offset[0], offset[1] or 0,
1401 'E901 %s: %s' % (exc_type.__name__, exc.args[0]),
1402 self.report_invalid_syntax)
1405 """Get the next line from the input buffer."""
1406 if self.line_number >= self.total_lines:
1408 line = self.lines[self.line_number]
1409 self.line_number += 1
1410 if self.indent_char is None and line[:1] in WHITESPACE:
1411 self.indent_char = line[0]
1414 def run_check(self, check, argument_names):
1415 """Run a check plugin."""
1417 for name in argument_names:
1418 arguments.append(getattr(self, name))
1419 return check(*arguments)
1421 def init_checker_state(self, name, argument_names):
1422 """ Prepares a custom state for the specific checker plugin."""
1423 if 'checker_state' in argument_names:
1424 self.checker_state = self._checker_states.setdefault(name, {})
1426 def check_physical(self, line):
1427 """Run all physical checks on a raw input line."""
1428 self.physical_line = line
1429 for name, check, argument_names in self._physical_checks:
1430 self.init_checker_state(name, argument_names)
1431 result = self.run_check(check, argument_names)
1432 if result is not None:
1433 (offset, text) = result
1434 self.report_error(self.line_number, offset, text, check)
1435 if text[:4] == 'E101':
1436 self.indent_char = line[0]
1438 def build_tokens_line(self):
1439 """Build a logical line from tokens."""
1443 prev_row = prev_col = mapping = None
1444 for token_type, text, start, end, line in self.tokens:
1445 if token_type in SKIP_TOKENS:
1448 mapping = [(0, start)]
1449 if token_type == tokenize.COMMENT:
1450 comments.append(text)
1452 if token_type == tokenize.STRING:
1453 text = mute_string(text)
1455 (start_row, start_col) = start
1456 if prev_row != start_row: # different row
1457 prev_text = self.lines[prev_row - 1][prev_col - 1]
1458 if prev_text == ',' or (prev_text not in '{[(' and
1461 elif prev_col != start_col: # different column
1462 text = line[prev_col:start_col] + text
1463 logical.append(text)
1465 mapping.append((length, end))
1466 (prev_row, prev_col) = end
1467 self.logical_line = ''.join(logical)
1468 self.noqa = comments and noqa(''.join(comments))
1471 def check_logical(self):
1472 """Build a line from tokens and run all logical checks on it."""
1473 self.report.increment_logical_line()
1474 mapping = self.build_tokens_line()
1479 (start_row, start_col) = mapping[0][1]
1480 start_line = self.lines[start_row - 1]
1481 self.indent_level = expand_indent(start_line[:start_col])
1482 if self.blank_before < self.blank_lines:
1483 self.blank_before = self.blank_lines
1484 if self.verbose >= 2:
1485 print(self.logical_line[:80].rstrip())
1486 for name, check, argument_names in self._logical_checks:
1487 if self.verbose >= 4:
1489 self.init_checker_state(name, argument_names)
1490 for offset, text in self.run_check(check, argument_names) or ():
1491 if not isinstance(offset, tuple):
1492 for token_offset, pos in mapping:
1493 if offset <= token_offset:
1495 offset = (pos[0], pos[1] + offset - token_offset)
1496 self.report_error(offset[0], offset[1], text, check)
1497 if self.logical_line:
1498 self.previous_indent_level = self.indent_level
1499 self.previous_logical = self.logical_line
1500 self.blank_lines = 0
1503 def check_ast(self):
1504 """Build the file's AST and run all AST checks."""
1506 tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST)
1507 except (SyntaxError, TypeError):
1508 return self.report_invalid_syntax()
1509 for name, cls, __ in self._ast_checks:
1510 checker = cls(tree, self.filename)
1511 for lineno, offset, text, check in checker.run():
1512 if not self.lines or not noqa(self.lines[lineno - 1]):
1513 self.report_error(lineno, offset, text, check)
1515 def generate_tokens(self):
1516 """Tokenize the file, run physical line checks and yield tokens."""
1518 self.report_error(1, 0, 'E902 %s' % self._io_error, readlines)
1519 tokengen = tokenize.generate_tokens(self.readline)
1521 for token in tokengen:
1522 if token[2][0] > self.total_lines:
1524 self.maybe_check_physical(token)
1526 except (SyntaxError, tokenize.TokenError):
1527 self.report_invalid_syntax()
1529 def maybe_check_physical(self, token):
1530 """If appropriate (based on token), check current physical line(s)."""
1531 # Called after every token, but act only on end of line.
1532 if _is_eol_token(token):
1533 # Obviously, a newline token ends a single physical line.
1534 self.check_physical(token[4])
1535 elif token[0] == tokenize.STRING and '\n' in token[1]:
1536 # Less obviously, a string that contains newlines is a
1537 # multiline string, either triple-quoted or with internal
1538 # newlines backslash-escaped. Check every physical line in the
1539 # string *except* for the last one: its newline is outside of
1540 # the multiline string, so we consider it a regular physical
1541 # line, and will check it like any other physical line.
1544 # - we don't *completely* ignore the last line; if it contains
1545 # the magical "# noqa" comment, we disable all physical
1546 # checks for the entire multiline string
1547 # - have to wind self.line_number back because initially it
1548 # points to the last line of the string, and we want
1549 # check_physical() to give accurate feedback
1552 self.multiline = True
1553 self.line_number = token[2][0]
1554 for line in token[1].split('\n')[:-1]:
1555 self.check_physical(line + '\n')
1556 self.line_number += 1
1557 self.multiline = False
1559 def check_all(self, expected=None, line_offset=0):
1560 """Run all checks on the input file."""
1561 self.report.init_file(self.filename, self.lines, expected, line_offset)
1562 self.total_lines = len(self.lines)
1563 if self._ast_checks:
1565 self.line_number = 0
1566 self.indent_char = None
1567 self.indent_level = self.previous_indent_level = 0
1568 self.previous_logical = ''
1570 self.blank_lines = self.blank_before = 0
1572 for token in self.generate_tokens():
1573 self.tokens.append(token)
1574 token_type, text = token[0:2]
1575 if self.verbose >= 3:
1576 if token[2][0] == token[3][0]:
1577 pos = '[%s:%s]' % (token[2][1] or '', token[3][1])
1579 pos = 'l.%s' % token[3][0]
1580 print('l.%s\t%s\t%s\t%r' %
1581 (token[2][0], pos, tokenize.tok_name[token[0]], text))
1582 if token_type == tokenize.OP:
1588 if token_type in NEWLINE:
1589 if token_type == tokenize.NEWLINE:
1590 self.check_logical()
1591 self.blank_before = 0
1592 elif len(self.tokens) == 1:
1593 # The physical line contains only this token.
1594 self.blank_lines += 1
1597 self.check_logical()
1598 elif COMMENT_WITH_NL and token_type == tokenize.COMMENT:
1599 if len(self.tokens) == 1:
1600 # The comment also ends a physical line
1602 token[1] = text.rstrip('\r\n')
1603 token[3] = (token[2][0], token[2][1] + len(token[1]))
1604 self.tokens = [tuple(token)]
1605 self.check_logical()
1607 self.check_physical(self.lines[-1])
1608 self.check_logical()
1609 return self.report.get_file_results()
1612 class BaseReport(object):
1613 """Collect the results of the checks."""
1615 print_filename = False
1617 def __init__(self, options):
1618 self._benchmark_keys = options.benchmark_keys
1619 self._ignore_code = options.ignore_code
1622 self.total_errors = 0
1623 self.counters = dict.fromkeys(self._benchmark_keys, 0)
1627 """Start the timer."""
1628 self._start_time = time.time()
1631 """Stop the timer."""
1632 self.elapsed = time.time() - self._start_time
1634 def init_file(self, filename, lines, expected, line_offset):
1635 """Signal a new file."""
1636 self.filename = filename
1638 self.expected = expected or ()
1639 self.line_offset = line_offset
1640 self.file_errors = 0
1641 self.counters['files'] += 1
1642 self.counters['physical lines'] += len(lines)
1644 def increment_logical_line(self):
1645 """Signal a new logical line."""
1646 self.counters['logical lines'] += 1
1648 def error(self, line_number, offset, text, check):
1649 """Report an error, according to options."""
1651 if self._ignore_code(code):
1653 if code in self.counters:
1654 self.counters[code] += 1
1656 self.counters[code] = 1
1657 self.messages[code] = text[5:]
1658 # Don't care about expected errors or warnings
1659 if code in self.expected:
1661 if self.print_filename and not self.file_errors:
1662 print(self.filename)
1663 self.file_errors += 1
1664 self.total_errors += 1
1667 def get_file_results(self):
1668 """Return the count of errors and warnings for this file."""
1669 return self.file_errors
1671 def get_count(self, prefix=''):
1672 """Return the total count of errors and warnings."""
1673 return sum([self.counters[key]
1674 for key in self.messages if key.startswith(prefix)])
1676 def get_statistics(self, prefix=''):
1677 """Get statistics for message codes that start with the prefix.
1679 prefix='' matches all errors and warnings
1680 prefix='E' matches all errors
1681 prefix='W' matches all warnings
1682 prefix='E4' matches all errors that have to do with imports
1684 return ['%-7s %s %s' % (self.counters[key], key, self.messages[key])
1685 for key in sorted(self.messages) if key.startswith(prefix)]
1687 def print_statistics(self, prefix=''):
1688 """Print overall statistics (number of errors and warnings)."""
1689 for line in self.get_statistics(prefix):
1692 def print_benchmark(self):
1693 """Print benchmark numbers."""
1694 print('%-7.2f %s' % (self.elapsed, 'seconds elapsed'))
1696 for key in self._benchmark_keys:
1697 print('%-7d %s per second (%d total)' %
1698 (self.counters[key] / self.elapsed, key,
1699 self.counters[key]))
1702 class FileReport(BaseReport):
1703 """Collect the results of the checks and print only the filenames."""
1704 print_filename = True
1707 class StandardReport(BaseReport):
1708 """Collect and print the results of the checks."""
1710 def __init__(self, options):
1711 super(StandardReport, self).__init__(options)
1712 self._fmt = REPORT_FORMAT.get(options.format.lower(),
1714 self._repeat = options.repeat
1715 self._show_source = options.show_source
1716 self._show_pep8 = options.show_pep8
1718 def init_file(self, filename, lines, expected, line_offset):
1719 """Signal a new file."""
1720 self._deferred_print = []
1721 return super(StandardReport, self).init_file(
1722 filename, lines, expected, line_offset)
1724 def error(self, line_number, offset, text, check):
1725 """Report an error, according to options."""
1726 code = super(StandardReport, self).error(line_number, offset,
1728 if code and (self.counters[code] == 1 or self._repeat):
1729 self._deferred_print.append(
1730 (line_number, offset, code, text[5:], check.__doc__))
1733 def get_file_results(self):
1734 """Print the result and return the overall count for this file."""
1735 self._deferred_print.sort()
1736 for line_number, offset, code, text, doc in self._deferred_print:
1738 'path': self.filename,
1739 'row': self.line_offset + line_number, 'col': offset + 1,
1740 'code': code, 'text': text,
1742 if self._show_source:
1743 if line_number > len(self.lines):
1746 line = self.lines[line_number - 1]
1747 print(line.rstrip())
1748 print(re.sub(r'\S', ' ', line[:offset]) + '^')
1749 if self._show_pep8 and doc:
1750 print(' ' + doc.strip())
1752 # stdout is block buffered when not stdout.isatty().
1753 # line can be broken where buffer boundary since other processes
1754 # write to same file.
1755 # flush() after print() to avoid buffer boundary.
1756 # Typical buffer size is 8192. line written safely when
1759 return self.file_errors
1762 class DiffReport(StandardReport):
1763 """Collect and print the results for the changed lines only."""
1765 def __init__(self, options):
1766 super(DiffReport, self).__init__(options)
1767 self._selected = options.selected_lines
1769 def error(self, line_number, offset, text, check):
1770 if line_number not in self._selected[self.filename]:
1772 return super(DiffReport, self).error(line_number, offset, text, check)
1775 class StyleGuide(object):
1776 """Initialize a PEP-8 instance with few options."""
1778 def __init__(self, *args, **kwargs):
1779 # build options from the command line
1780 self.checker_class = kwargs.pop('checker_class', Checker)
1781 parse_argv = kwargs.pop('parse_argv', False)
1782 config_file = kwargs.pop('config_file', False)
1783 parser = kwargs.pop('parser', None)
1784 # build options from dict
1785 options_dict = dict(*args, **kwargs)
1786 arglist = None if parse_argv else options_dict.get('paths', None)
1787 options, self.paths = process_options(
1788 arglist, parse_argv, config_file, parser)
1790 options.__dict__.update(options_dict)
1791 if 'paths' in options_dict:
1792 self.paths = options_dict['paths']
1794 self.runner = self.input_file
1795 self.options = options
1797 if not options.reporter:
1798 options.reporter = BaseReport if options.quiet else StandardReport
1800 options.select = tuple(options.select or ())
1801 if not (options.select or options.ignore or
1802 options.testsuite or options.doctest) and DEFAULT_IGNORE:
1803 # The default choice: ignore controversial checks
1804 options.ignore = tuple(DEFAULT_IGNORE.split(','))
1806 # Ignore all checks which are not explicitly selected
1807 options.ignore = ('',) if options.select else tuple(options.ignore)
1808 options.benchmark_keys = BENCHMARK_KEYS[:]
1809 options.ignore_code = self.ignore_code
1810 options.physical_checks = self.get_checks('physical_line')
1811 options.logical_checks = self.get_checks('logical_line')
1812 options.ast_checks = self.get_checks('tree')
1815 def init_report(self, reporter=None):
1816 """Initialize the report instance."""
1817 self.options.report = (reporter or self.options.reporter)(self.options)
1818 return self.options.report
1820 def check_files(self, paths=None):
1821 """Run all checks on the paths."""
1824 report = self.options.report
1825 runner = self.runner
1829 if os.path.isdir(path):
1830 self.input_dir(path)
1831 elif not self.excluded(path):
1833 except KeyboardInterrupt:
1834 print('... stopped')
1838 def input_file(self, filename, lines=None, expected=None, line_offset=0):
1839 """Run all checks on a Python source file."""
1840 if self.options.verbose:
1841 print('checking %s' % filename)
1842 fchecker = self.checker_class(
1843 filename, lines=lines, options=self.options)
1844 return fchecker.check_all(expected=expected, line_offset=line_offset)
1846 def input_dir(self, dirname):
1847 """Check all files in this directory and all subdirectories."""
1848 dirname = dirname.rstrip('/')
1849 if self.excluded(dirname):
1851 counters = self.options.report.counters
1852 verbose = self.options.verbose
1853 filepatterns = self.options.filename
1854 runner = self.runner
1855 for root, dirs, files in os.walk(dirname):
1857 print('directory ' + root)
1858 counters['directories'] += 1
1859 for subdir in sorted(dirs):
1860 if self.excluded(subdir, root):
1862 for filename in sorted(files):
1863 # contain a pattern that matches?
1864 if ((filename_match(filename, filepatterns) and
1865 not self.excluded(filename, root))):
1866 runner(os.path.join(root, filename))
1868 def excluded(self, filename, parent=None):
1869 """Check if the file should be excluded.
1871 Check if 'options.exclude' contains a pattern that matches filename.
1873 if not self.options.exclude:
1875 basename = os.path.basename(filename)
1876 if filename_match(basename, self.options.exclude):
1879 filename = os.path.join(parent, filename)
1880 filename = os.path.abspath(filename)
1881 return filename_match(filename, self.options.exclude)
1883 def ignore_code(self, code):
1884 """Check if the error code should be ignored.
1886 If 'options.select' contains a prefix of the error code,
1887 return False. Else, if 'options.ignore' contains a prefix of
1888 the error code, return True.
1890 if len(code) < 4 and any(s.startswith(code)
1891 for s in self.options.select):
1893 return (code.startswith(self.options.ignore) and
1894 not code.startswith(self.options.select))
1896 def get_checks(self, argument_name):
1897 """Get all the checks for this category.
1899 Find all globally visible functions where the first argument name
1900 starts with argument_name and which contain selected tests.
1903 for check, attrs in _checks[argument_name].items():
1904 (codes, args) = attrs
1905 if any(not (code and self.ignore_code(code)) for code in codes):
1906 checks.append((check.__name__, check, args))
1907 return sorted(checks)
1910 def get_parser(prog='pep8', version=__version__):
1911 parser = OptionParser(prog=prog, version=version,
1912 usage="%prog [options] input ...")
1913 parser.config_options = [
1914 'exclude', 'filename', 'select', 'ignore', 'max-line-length',
1915 'hang-closing', 'count', 'format', 'quiet', 'show-pep8',
1916 'show-source', 'statistics', 'verbose']
1917 parser.add_option('-v', '--verbose', default=0, action='count',
1918 help="print status messages, or debug with -vv")
1919 parser.add_option('-q', '--quiet', default=0, action='count',
1920 help="report only file names, or nothing with -qq")
1921 parser.add_option('-r', '--repeat', default=True, action='store_true',
1922 help="(obsolete) show all occurrences of the same error")
1923 parser.add_option('--first', action='store_false', dest='repeat',
1924 help="show first occurrence of each error")
1925 parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE,
1926 help="exclude files or directories which match these "
1927 "comma separated patterns (default: %default)")
1928 parser.add_option('--filename', metavar='patterns', default='*.py',
1929 help="when parsing directories, only check filenames "
1930 "matching these comma separated patterns "
1931 "(default: %default)")
1932 parser.add_option('--select', metavar='errors', default='',
1933 help="select errors and warnings (e.g. E,W6)")
1934 parser.add_option('--ignore', metavar='errors', default='',
1935 help="skip errors and warnings (e.g. E4,W) "
1936 "(default: %s)" % DEFAULT_IGNORE)
1937 parser.add_option('--show-source', action='store_true',
1938 help="show source code for each error")
1939 parser.add_option('--show-pep8', action='store_true',
1940 help="show text of PEP 8 for each error "
1941 "(implies --first)")
1942 parser.add_option('--statistics', action='store_true',
1943 help="count errors and warnings")
1944 parser.add_option('--count', action='store_true',
1945 help="print total number of errors and warnings "
1946 "to standard error and set exit code to 1 if "
1947 "total is not null")
1948 parser.add_option('--max-line-length', type='int', metavar='n',
1949 default=MAX_LINE_LENGTH,
1950 help="set maximum allowed line length "
1951 "(default: %default)")
1952 parser.add_option('--hang-closing', action='store_true',
1953 help="hang closing bracket instead of matching "
1954 "indentation of opening bracket's line")
1955 parser.add_option('--format', metavar='format', default='default',
1956 help="set the error format [default|pylint|<custom>]")
1957 parser.add_option('--diff', action='store_true',
1958 help="report only lines changed according to the "
1959 "unified diff received on STDIN")
1960 group = parser.add_option_group("Testing Options")
1961 if os.path.exists(TESTSUITE_PATH):
1962 group.add_option('--testsuite', metavar='dir',
1963 help="run regression tests from dir")
1964 group.add_option('--doctest', action='store_true',
1965 help="run doctest on myself")
1966 group.add_option('--benchmark', action='store_true',
1967 help="measure processing speed")
1971 def read_config(options, args, arglist, parser):
1972 """Read and parse configurations
1974 If a config file is specified on the command line with the "--config"
1975 option, then only it is used for configuration.
1977 Otherwise, the user configuration (~/.config/pep8) and any local
1978 configurations in the current directory or above will be merged together
1979 (in that order) using the read method of ConfigParser.
1981 config = RawConfigParser()
1983 cli_conf = options.config
1985 local_dir = os.curdir
1987 if cli_conf and os.path.isfile(cli_conf):
1989 print('cli configuration: %s' % cli_conf)
1990 config.read(cli_conf)
1992 if USER_CONFIG and os.path.isfile(USER_CONFIG):
1994 print('user configuration: %s' % USER_CONFIG)
1995 config.read(USER_CONFIG)
1997 parent = tail = args and os.path.abspath(os.path.commonprefix(args))
1999 if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG):
2002 print('local configuration: in %s' % parent)
2004 (parent, tail) = os.path.split(parent)
2006 pep8_section = parser.prog
2007 if config.has_section(pep8_section):
2008 option_list = dict([(o.dest, o.type or o.action)
2009 for o in parser.option_list])
2011 # First, read the default values
2012 (new_options, __) = parser.parse_args([])
2014 # Second, parse the configuration
2015 for opt in config.options(pep8_section):
2016 if opt.replace('_', '-') not in parser.config_options:
2017 print(" unknown option '%s' ignored" % opt)
2019 if options.verbose > 1:
2020 print(" %s = %s" % (opt, config.get(pep8_section, opt)))
2021 normalized_opt = opt.replace('-', '_')
2022 opt_type = option_list[normalized_opt]
2023 if opt_type in ('int', 'count'):
2024 value = config.getint(pep8_section, opt)
2025 elif opt_type == 'string':
2026 value = config.get(pep8_section, opt)
2027 if normalized_opt == 'exclude':
2028 value = normalize_paths(value, local_dir)
2030 assert opt_type in ('store_true', 'store_false')
2031 value = config.getboolean(pep8_section, opt)
2032 setattr(new_options, normalized_opt, value)
2034 # Third, overwrite with the command-line options
2035 (options, __) = parser.parse_args(arglist, values=new_options)
2036 options.doctest = options.testsuite = False
2040 def process_options(arglist=None, parse_argv=False, config_file=None,
2042 """Process options passed either via arglist or via command line args.
2044 Passing in the ``config_file`` parameter allows other tools, such as flake8
2045 to specify their own options to be processed in pep8.
2048 parser = get_parser()
2049 if not parser.has_option('--config'):
2050 group = parser.add_option_group("Configuration", description=(
2051 "The project options are read from the [%s] section of the "
2052 "tox.ini file or the setup.cfg file located in any parent folder "
2053 "of the path(s) being processed. Allowed options are: %s." %
2054 (parser.prog, ', '.join(parser.config_options))))
2055 group.add_option('--config', metavar='path', default=config_file,
2056 help="user config file location")
2057 # Don't read the command line if the module is used as a library.
2058 if not arglist and not parse_argv:
2060 # If parse_argv is True and arglist is None, arguments are
2061 # parsed from the command line (sys.argv)
2062 (options, args) = parser.parse_args(arglist)
2063 options.reporter = None
2065 if options.ensure_value('testsuite', False):
2066 args.append(options.testsuite)
2067 elif not options.ensure_value('doctest', False):
2068 if parse_argv and not args:
2069 if options.diff or any(os.path.exists(name)
2070 for name in PROJECT_CONFIG):
2073 parser.error('input not specified')
2074 options = read_config(options, args, arglist, parser)
2075 options.reporter = parse_argv and options.quiet == 1 and FileReport
2077 options.filename = options.filename and options.filename.split(',')
2078 options.exclude = normalize_paths(options.exclude)
2079 options.select = options.select and options.select.split(',')
2080 options.ignore = options.ignore and options.ignore.split(',')
2083 options.reporter = DiffReport
2084 stdin = stdin_get_value()
2085 options.selected_lines = parse_udiff(stdin, options.filename, args[0])
2086 args = sorted(options.selected_lines)
2088 return options, args
2092 """Parse options and run checks on Python source."""
2095 # Handle "Broken pipe" gracefully
2097 signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1))
2098 except AttributeError:
2099 pass # not supported on Windows
2101 pep8style = StyleGuide(parse_argv=True)
2102 options = pep8style.options
2103 if options.doctest or options.testsuite:
2104 from testsuite.support import run_tests
2105 report = run_tests(pep8style)
2107 report = pep8style.check_files()
2108 if options.statistics:
2109 report.print_statistics()
2110 if options.benchmark:
2111 report.print_benchmark()
2112 if options.testsuite and not options.quiet:
2113 report.print_results()
2114 if report.total_errors:
2116 sys.stderr.write(str(report.total_errors) + '\n')
2119 if __name__ == '__main__':
def maximum_line_length(physical_line, max_line_length, multiline)
def python_3000_backticks(logical_line)
def module_imports_on_top_of_file(logical_line, indent_level, checker_state, noqa)
def comparison_type(logical_line, noqa)
def whitespace_around_keywords(logical_line)
def missing_whitespace(logical_line)
def trailing_whitespace(physical_line)
def whitespace_around_named_parameter_equals(logical_line, tokens)
def tabs_obsolete(physical_line)
def continued_indentation(logical_line, tokens, indent_level, hang_closing, indent_char, noqa, verbose)
def indentation(logical_line, previous_logical, indent_char, indent_level, previous_indent_level)
def missing_whitespace_around_operator(logical_line, tokens)
def whitespace_before_parameters(logical_line, tokens)
def readlines(filename)
Helper functions.
def comparison_to_singleton(logical_line, noqa)
def trailing_blank_lines(physical_line, lines, line_number, total_lines)
def blank_lines(logical_line, blank_lines, indent_level, line_number, blank_before, previous_logical, previous_indent_level)
Plugins (check functions) for logical lines.
def break_around_binary_operator(logical_line, tokens)
def python_3000_has_key(logical_line, noqa)
def whitespace_before_comment(logical_line, tokens)
def tabs_or_spaces(physical_line, indent_char)
Plugins (check functions) for physical lines.
def python_3000_not_equal(logical_line)
def python_3000_raise_comma(logical_line)
def explicit_line_join(logical_line, tokens)
def whitespace_around_comma(logical_line)
def whitespace_around_operator(logical_line)
def compound_statements(logical_line)
def extraneous_whitespace(logical_line)
def comparison_negative(logical_line)
def imports_on_separate_lines(logical_line)