Update docs for configuration
[third_party/pep8] / pep8.py
1 #!/usr/bin/env python
2 # pep8.py - Check Python source code formatting, according to PEP 8
3 # Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net>
4 # Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com>
5 # Copyright (C) 2014 Ian Lee <ianlee1521@gmail.com>
6 #
7 # Permission is hereby granted, free of charge, to any person
8 # obtaining a copy of this software and associated documentation files
9 # (the "Software"), to deal in the Software without restriction,
10 # including without limitation the rights to use, copy, modify, merge,
11 # publish, distribute, sublicense, and/or sell copies of the Software,
12 # and to permit persons to whom the Software is furnished to do so,
13 # subject to the following conditions:
14 #
15 # The above copyright notice and this permission notice shall be
16 # included in all copies or substantial portions of the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 # SOFTWARE.
26
27 r"""
28 Check Python source code formatting, according to PEP 8.
29
30 For usage and a list of options, try this:
31 $ python pep8.py -h
32
33 This program and its regression test suite live here:
34 http://github.com/jcrocholl/pep8
35
36 Groups of errors and warnings:
37 E errors
38 W warnings
39 100 indentation
40 200 whitespace
41 300 blank lines
42 400 imports
43 500 line length
44 600 deprecation
45 700 statements
46 900 syntax error
47 """
48 from __future__ import with_statement
49
50 import os
51 import sys
52 import re
53 import time
54 import inspect
55 import keyword
56 import tokenize
57 from optparse import OptionParser
58 from fnmatch import fnmatch
59 try:
60     from configparser import RawConfigParser
61     from io import TextIOWrapper
62 except ImportError:
63     from ConfigParser import RawConfigParser
64
65 __version__ = '1.6.0a0'
66
67 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox'
68 DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704'
69 try:
70     if sys.platform == 'win32':
71         DEFAULT_CONFIG = os.path.expanduser(r'~\.pep8')
72     else:
73         DEFAULT_CONFIG = os.path.join(os.getenv('XDG_CONFIG_HOME') or
74                                       os.path.expanduser('~/.config'), 'pep8')
75 except ImportError:
76     DEFAULT_CONFIG = None
77
78 PROJECT_CONFIG = ('setup.cfg', 'tox.ini', '.pep8')
79 TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite')
80 MAX_LINE_LENGTH = 79
81 REPORT_FORMAT = {
82     'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s',
83     'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s',
84 }
85
86 PyCF_ONLY_AST = 1024
87 SINGLETONS = frozenset(['False', 'None', 'True'])
88 KEYWORDS = frozenset(keyword.kwlist + ['print']) - SINGLETONS
89 UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-'])
90 ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-'])
91 WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%'])
92 WS_NEEDED_OPERATORS = frozenset([
93     '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<>', '<', '>',
94     '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '='])
95 WHITESPACE = frozenset(' \t')
96 NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE])
97 SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT])
98 # ERRORTOKEN is triggered by backticks in Python 3
99 SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN])
100 BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines']
101
102 INDENT_REGEX = re.compile(r'([ \t]*)')
103 RAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,')
104 RERAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,.*,\s*\w+\s*$')
105 ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b')
106 DOCSTRING_REGEX = re.compile(r'u?r?["\']')
107 EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[[({] | []}),;:]')
108 WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?:  |\t)')
109 COMPARE_SINGLETON_REGEX = re.compile(r'\b(None|False|True)?\s*([=!]=)'
110                                      r'\s*(?(1)|(None|False|True))\b')
111 COMPARE_NEGATIVE_REGEX = re.compile(r'\b(not)\s+[^][)(}{ ]+\s+(in|is)\s')
112 COMPARE_TYPE_REGEX = re.compile(r'(?:[=!]=|is(?:\s+not)?)\s*type(?:s.\w+Type'
113                                 r'|\s*\(\s*([^)]*[^ )])\s*\))')
114 KEYWORD_REGEX = re.compile(r'(\s*)\b(?:%s)\b(\s*)' % r'|'.join(KEYWORDS))
115 OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)')
116 LAMBDA_REGEX = re.compile(r'\blambda\b')
117 HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$')
118
119 # Work around Python < 2.6 behaviour, which does not generate NL after
120 # a comment which is on a line by itself.
121 COMMENT_WITH_NL = tokenize.generate_tokens(['#\n'].pop).send(None)[1] == '#\n'
122
123
124 ##############################################################################
125 # Plugins (check functions) for physical lines
126 ##############################################################################
127
128
129 def tabs_or_spaces(physical_line, indent_char):
130     r"""Never mix tabs and spaces.
131
132     The most popular way of indenting Python is with spaces only.  The
133     second-most popular way is with tabs only.  Code indented with a mixture
134     of tabs and spaces should be converted to using spaces exclusively.  When
135     invoking the Python command line interpreter with the -t option, it issues
136     warnings about code that illegally mixes tabs and spaces.  When using -tt
137     these warnings become errors.  These options are highly recommended!
138
139     Okay: if a == 0:\n        a = 1\n        b = 1
140     E101: if a == 0:\n        a = 1\n\tb = 1
141     """
142     indent = INDENT_REGEX.match(physical_line).group(1)
143     for offset, char in enumerate(indent):
144         if char != indent_char:
145             return offset, "E101 indentation contains mixed spaces and tabs"
146
147
148 def tabs_obsolete(physical_line):
149     r"""For new projects, spaces-only are strongly recommended over tabs.
150
151     Okay: if True:\n    return
152     W191: if True:\n\treturn
153     """
154     indent = INDENT_REGEX.match(physical_line).group(1)
155     if '\t' in indent:
156         return indent.index('\t'), "W191 indentation contains tabs"
157
158
159 def trailing_whitespace(physical_line):
160     r"""Trailing whitespace is superfluous.
161
162     The warning returned varies on whether the line itself is blank, for easier
163     filtering for those who want to indent their blank lines.
164
165     Okay: spam(1)\n#
166     W291: spam(1) \n#
167     W293: class Foo(object):\n    \n    bang = 12
168     """
169     physical_line = physical_line.rstrip('\n')    # chr(10), newline
170     physical_line = physical_line.rstrip('\r')    # chr(13), carriage return
171     physical_line = physical_line.rstrip('\x0c')  # chr(12), form feed, ^L
172     stripped = physical_line.rstrip(' \t\v')
173     if physical_line != stripped:
174         if stripped:
175             return len(stripped), "W291 trailing whitespace"
176         else:
177             return 0, "W293 blank line contains whitespace"
178
179
180 def trailing_blank_lines(physical_line, lines, line_number, total_lines):
181     r"""Trailing blank lines are superfluous.
182
183     Okay: spam(1)
184     W391: spam(1)\n
185
186     However the last line should end with a new line (warning W292).
187     """
188     if line_number == total_lines:
189         stripped_last_line = physical_line.rstrip()
190         if not stripped_last_line:
191             return 0, "W391 blank line at end of file"
192         if stripped_last_line == physical_line:
193             return len(physical_line), "W292 no newline at end of file"
194
195
196 def maximum_line_length(physical_line, max_line_length, multiline):
197     r"""Limit all lines to a maximum of 79 characters.
198
199     There are still many devices around that are limited to 80 character
200     lines; plus, limiting windows to 80 characters makes it possible to have
201     several windows side-by-side.  The default wrapping on such devices looks
202     ugly.  Therefore, please limit all lines to a maximum of 79 characters.
203     For flowing long blocks of text (docstrings or comments), limiting the
204     length to 72 characters is recommended.
205
206     Reports error E501.
207     """
208     line = physical_line.rstrip()
209     length = len(line)
210     if length > max_line_length and not noqa(line):
211         # Special case for long URLs in multi-line docstrings or comments,
212         # but still report the error when the 72 first chars are whitespaces.
213         chunks = line.split()
214         if ((len(chunks) == 1 and multiline) or
215             (len(chunks) == 2 and chunks[0] == '#')) and \
216                 len(line) - len(chunks[-1]) < max_line_length - 7:
217             return
218         if hasattr(line, 'decode'):   # Python 2
219             # The line could contain multi-byte characters
220             try:
221                 length = len(line.decode('utf-8'))
222             except UnicodeError:
223                 pass
224         if length > max_line_length:
225             return (max_line_length, "E501 line too long "
226                     "(%d > %d characters)" % (length, max_line_length))
227
228
229 ##############################################################################
230 # Plugins (check functions) for logical lines
231 ##############################################################################
232
233
234 def blank_lines(logical_line, blank_lines, indent_level, line_number,
235                 blank_before, previous_logical, previous_indent_level):
236     r"""Separate top-level function and class definitions with two blank lines.
237
238     Method definitions inside a class are separated by a single blank line.
239
240     Extra blank lines may be used (sparingly) to separate groups of related
241     functions.  Blank lines may be omitted between a bunch of related
242     one-liners (e.g. a set of dummy implementations).
243
244     Use blank lines in functions, sparingly, to indicate logical sections.
245
246     Okay: def a():\n    pass\n\n\ndef b():\n    pass
247     Okay: def a():\n    pass\n\n\n# Foo\n# Bar\n\ndef b():\n    pass
248
249     E301: class Foo:\n    b = 0\n    def bar():\n        pass
250     E302: def a():\n    pass\n\ndef b(n):\n    pass
251     E303: def a():\n    pass\n\n\n\ndef b(n):\n    pass
252     E303: def a():\n\n\n\n    pass
253     E304: @decorator\n\ndef a():\n    pass
254     """
255     if line_number < 3 and not previous_logical:
256         return  # Don't expect blank lines before the first line
257     if previous_logical.startswith('@'):
258         if blank_lines:
259             yield 0, "E304 blank lines found after function decorator"
260     elif blank_lines > 2 or (indent_level and blank_lines == 2):
261         yield 0, "E303 too many blank lines (%d)" % blank_lines
262     elif logical_line.startswith(('def ', 'class ', '@')):
263         if indent_level:
264             if not (blank_before or previous_indent_level < indent_level or
265                     DOCSTRING_REGEX.match(previous_logical)):
266                 yield 0, "E301 expected 1 blank line, found 0"
267         elif blank_before != 2:
268             yield 0, "E302 expected 2 blank lines, found %d" % blank_before
269
270
271 def extraneous_whitespace(logical_line):
272     r"""Avoid extraneous whitespace.
273
274     Avoid extraneous whitespace in these situations:
275     - Immediately inside parentheses, brackets or braces.
276     - Immediately before a comma, semicolon, or colon.
277
278     Okay: spam(ham[1], {eggs: 2})
279     E201: spam( ham[1], {eggs: 2})
280     E201: spam(ham[ 1], {eggs: 2})
281     E201: spam(ham[1], { eggs: 2})
282     E202: spam(ham[1], {eggs: 2} )
283     E202: spam(ham[1 ], {eggs: 2})
284     E202: spam(ham[1], {eggs: 2 })
285
286     E203: if x == 4: print x, y; x, y = y , x
287     E203: if x == 4: print x, y ; x, y = y, x
288     E203: if x == 4 : print x, y; x, y = y, x
289     """
290     line = logical_line
291     for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line):
292         text = match.group()
293         char = text.strip()
294         found = match.start()
295         if text == char + ' ':
296             # assert char in '([{'
297             yield found + 1, "E201 whitespace after '%s'" % char
298         elif line[found - 1] != ',':
299             code = ('E202' if char in '}])' else 'E203')  # if char in ',;:'
300             yield found, "%s whitespace before '%s'" % (code, char)
301
302
303 def whitespace_around_keywords(logical_line):
304     r"""Avoid extraneous whitespace around keywords.
305
306     Okay: True and False
307     E271: True and  False
308     E272: True  and False
309     E273: True and\tFalse
310     E274: True\tand False
311     """
312     for match in KEYWORD_REGEX.finditer(logical_line):
313         before, after = match.groups()
314
315         if '\t' in before:
316             yield match.start(1), "E274 tab before keyword"
317         elif len(before) > 1:
318             yield match.start(1), "E272 multiple spaces before keyword"
319
320         if '\t' in after:
321             yield match.start(2), "E273 tab after keyword"
322         elif len(after) > 1:
323             yield match.start(2), "E271 multiple spaces after keyword"
324
325
326 def missing_whitespace(logical_line):
327     r"""Each comma, semicolon or colon should be followed by whitespace.
328
329     Okay: [a, b]
330     Okay: (3,)
331     Okay: a[1:4]
332     Okay: a[:4]
333     Okay: a[1:]
334     Okay: a[1:4:2]
335     E231: ['a','b']
336     E231: foo(bar,baz)
337     E231: [{'a':'b'}]
338     """
339     line = logical_line
340     for index in range(len(line) - 1):
341         char = line[index]
342         if char in ',;:' and line[index + 1] not in WHITESPACE:
343             before = line[:index]
344             if char == ':' and before.count('[') > before.count(']') and \
345                     before.rfind('{') < before.rfind('['):
346                 continue  # Slice syntax, no space required
347             if char == ',' and line[index + 1] == ')':
348                 continue  # Allow tuple with only one element: (3,)
349             yield index, "E231 missing whitespace after '%s'" % char
350
351
352 def indentation(logical_line, previous_logical, indent_char,
353                 indent_level, previous_indent_level):
354     r"""Use 4 spaces per indentation level.
355
356     For really old code that you don't want to mess up, you can continue to
357     use 8-space tabs.
358
359     Okay: a = 1
360     Okay: if a == 0:\n    a = 1
361     E111:   a = 1
362     E114:   # a = 1
363
364     Okay: for item in items:\n    pass
365     E112: for item in items:\npass
366     E115: for item in items:\n# Hi\n    pass
367
368     Okay: a = 1\nb = 2
369     E113: a = 1\n    b = 2
370     E116: a = 1\n    # b = 2
371     """
372     c = 0 if logical_line else 3
373     tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)"
374     if indent_level % 4:
375         yield 0, tmpl % (1 + c, "indentation is not a multiple of four")
376     indent_expect = previous_logical.endswith(':')
377     if indent_expect and indent_level <= previous_indent_level:
378         yield 0, tmpl % (2 + c, "expected an indented block")
379     elif not indent_expect and indent_level > previous_indent_level:
380         yield 0, tmpl % (3 + c, "unexpected indentation")
381
382
383 def continued_indentation(logical_line, tokens, indent_level, hang_closing,
384                           indent_char, noqa, verbose):
385     r"""Continuation lines indentation.
386
387     Continuation lines should align wrapped elements either vertically
388     using Python's implicit line joining inside parentheses, brackets
389     and braces, or using a hanging indent.
390
391     When using a hanging indent these considerations should be applied:
392     - there should be no arguments on the first line, and
393     - further indentation should be used to clearly distinguish itself as a
394       continuation line.
395
396     Okay: a = (\n)
397     E123: a = (\n    )
398
399     Okay: a = (\n    42)
400     E121: a = (\n   42)
401     E122: a = (\n42)
402     E123: a = (\n    42\n    )
403     E124: a = (24,\n     42\n)
404     E125: if (\n    b):\n    pass
405     E126: a = (\n        42)
406     E127: a = (24,\n      42)
407     E128: a = (24,\n    42)
408     E129: if (a or\n    b):\n    pass
409     E131: a = (\n    42\n 24)
410     """
411     first_row = tokens[0][2][0]
412     nrows = 1 + tokens[-1][2][0] - first_row
413     if noqa or nrows == 1:
414         return
415
416     # indent_next tells us whether the next block is indented; assuming
417     # that it is indented by 4 spaces, then we should not allow 4-space
418     # indents on the final continuation line; in turn, some other
419     # indents are allowed to have an extra 4 spaces.
420     indent_next = logical_line.endswith(':')
421
422     row = depth = 0
423     valid_hangs = (4,) if indent_char != '\t' else (4, 8)
424     # remember how many brackets were opened on each line
425     parens = [0] * nrows
426     # relative indents of physical lines
427     rel_indent = [0] * nrows
428     # for each depth, collect a list of opening rows
429     open_rows = [[0]]
430     # for each depth, memorize the hanging indentation
431     hangs = [None]
432     # visual indents
433     indent_chances = {}
434     last_indent = tokens[0][2]
435     visual_indent = None
436     # for each depth, memorize the visual indent column
437     indent = [last_indent[1]]
438     if verbose >= 3:
439         print(">>> " + tokens[0][4].rstrip())
440
441     for token_type, text, start, end, line in tokens:
442
443         newline = row < start[0] - first_row
444         if newline:
445             row = start[0] - first_row
446             newline = not last_token_multiline and token_type not in NEWLINE
447
448         if newline:
449             # this is the beginning of a continuation line.
450             last_indent = start
451             if verbose >= 3:
452                 print("... " + line.rstrip())
453
454             # record the initial indent.
455             rel_indent[row] = expand_indent(line) - indent_level
456
457             # identify closing bracket
458             close_bracket = (token_type == tokenize.OP and text in ']})')
459
460             # is the indent relative to an opening bracket line?
461             for open_row in reversed(open_rows[depth]):
462                 hang = rel_indent[row] - rel_indent[open_row]
463                 hanging_indent = hang in valid_hangs
464                 if hanging_indent:
465                     break
466             if hangs[depth]:
467                 hanging_indent = (hang == hangs[depth])
468             # is there any chance of visual indent?
469             visual_indent = (not close_bracket and hang > 0 and
470                              indent_chances.get(start[1]))
471
472             if close_bracket and indent[depth]:
473                 # closing bracket for visual indent
474                 if start[1] != indent[depth]:
475                     yield (start, "E124 closing bracket does not match "
476                            "visual indentation")
477             elif close_bracket and not hang:
478                 # closing bracket matches indentation of opening bracket's line
479                 if hang_closing:
480                     yield start, "E133 closing bracket is missing indentation"
481             elif indent[depth] and start[1] < indent[depth]:
482                 if visual_indent is not True:
483                     # visual indent is broken
484                     yield (start, "E128 continuation line "
485                            "under-indented for visual indent")
486             elif hanging_indent or (indent_next and rel_indent[row] == 8):
487                 # hanging indent is verified
488                 if close_bracket and not hang_closing:
489                     yield (start, "E123 closing bracket does not match "
490                            "indentation of opening bracket's line")
491                 hangs[depth] = hang
492             elif visual_indent is True:
493                 # visual indent is verified
494                 indent[depth] = start[1]
495             elif visual_indent in (text, str):
496                 # ignore token lined up with matching one from a previous line
497                 pass
498             else:
499                 # indent is broken
500                 if hang <= 0:
501                     error = "E122", "missing indentation or outdented"
502                 elif indent[depth]:
503                     error = "E127", "over-indented for visual indent"
504                 elif not close_bracket and hangs[depth]:
505                     error = "E131", "unaligned for hanging indent"
506                 else:
507                     hangs[depth] = hang
508                     if hang > 4:
509                         error = "E126", "over-indented for hanging indent"
510                     else:
511                         error = "E121", "under-indented for hanging indent"
512                 yield start, "%s continuation line %s" % error
513
514         # look for visual indenting
515         if (parens[row] and token_type not in (tokenize.NL, tokenize.COMMENT)
516                 and not indent[depth]):
517             indent[depth] = start[1]
518             indent_chances[start[1]] = True
519             if verbose >= 4:
520                 print("bracket depth %s indent to %s" % (depth, start[1]))
521         # deal with implicit string concatenation
522         elif (token_type in (tokenize.STRING, tokenize.COMMENT) or
523               text in ('u', 'ur', 'b', 'br')):
524             indent_chances[start[1]] = str
525         # special case for the "if" statement because len("if (") == 4
526         elif not indent_chances and not row and not depth and text == 'if':
527             indent_chances[end[1] + 1] = True
528         elif text == ':' and line[end[1]:].isspace():
529             open_rows[depth].append(row)
530
531         # keep track of bracket depth
532         if token_type == tokenize.OP:
533             if text in '([{':
534                 depth += 1
535                 indent.append(0)
536                 hangs.append(None)
537                 if len(open_rows) == depth:
538                     open_rows.append([])
539                 open_rows[depth].append(row)
540                 parens[row] += 1
541                 if verbose >= 4:
542                     print("bracket depth %s seen, col %s, visual min = %s" %
543                           (depth, start[1], indent[depth]))
544             elif text in ')]}' and depth > 0:
545                 # parent indents should not be more than this one
546                 prev_indent = indent.pop() or last_indent[1]
547                 hangs.pop()
548                 for d in range(depth):
549                     if indent[d] > prev_indent:
550                         indent[d] = 0
551                 for ind in list(indent_chances):
552                     if ind >= prev_indent:
553                         del indent_chances[ind]
554                 del open_rows[depth + 1:]
555                 depth -= 1
556                 if depth:
557                     indent_chances[indent[depth]] = True
558                 for idx in range(row, -1, -1):
559                     if parens[idx]:
560                         parens[idx] -= 1
561                         break
562             assert len(indent) == depth + 1
563             if start[1] not in indent_chances:
564                 # allow to line up tokens
565                 indent_chances[start[1]] = text
566
567         last_token_multiline = (start[0] != end[0])
568         if last_token_multiline:
569             rel_indent[end[0] - first_row] = rel_indent[row]
570
571     if indent_next and expand_indent(line) == indent_level + 4:
572         pos = (start[0], indent[0] + 4)
573         if visual_indent:
574             code = "E129 visually indented line"
575         else:
576             code = "E125 continuation line"
577         yield pos, "%s with same indent as next logical line" % code
578
579
580 def whitespace_before_parameters(logical_line, tokens):
581     r"""Avoid extraneous whitespace.
582
583     Avoid extraneous whitespace in the following situations:
584     - before the open parenthesis that starts the argument list of a
585       function call.
586     - before the open parenthesis that starts an indexing or slicing.
587
588     Okay: spam(1)
589     E211: spam (1)
590
591     Okay: dict['key'] = list[index]
592     E211: dict ['key'] = list[index]
593     E211: dict['key'] = list [index]
594     """
595     prev_type, prev_text, __, prev_end, __ = tokens[0]
596     for index in range(1, len(tokens)):
597         token_type, text, start, end, __ = tokens[index]
598         if (token_type == tokenize.OP and
599             text in '([' and
600             start != prev_end and
601             (prev_type == tokenize.NAME or prev_text in '}])') and
602             # Syntax "class A (B):" is allowed, but avoid it
603             (index < 2 or tokens[index - 2][1] != 'class') and
604                 # Allow "return (a.foo for a in range(5))"
605                 not keyword.iskeyword(prev_text)):
606             yield prev_end, "E211 whitespace before '%s'" % text
607         prev_type = token_type
608         prev_text = text
609         prev_end = end
610
611
612 def whitespace_around_operator(logical_line):
613     r"""Avoid extraneous whitespace around an operator.
614
615     Okay: a = 12 + 3
616     E221: a = 4  + 5
617     E222: a = 4 +  5
618     E223: a = 4\t+ 5
619     E224: a = 4 +\t5
620     """
621     for match in OPERATOR_REGEX.finditer(logical_line):
622         before, after = match.groups()
623
624         if '\t' in before:
625             yield match.start(1), "E223 tab before operator"
626         elif len(before) > 1:
627             yield match.start(1), "E221 multiple spaces before operator"
628
629         if '\t' in after:
630             yield match.start(2), "E224 tab after operator"
631         elif len(after) > 1:
632             yield match.start(2), "E222 multiple spaces after operator"
633
634
635 def missing_whitespace_around_operator(logical_line, tokens):
636     r"""Surround operators with a single space on either side.
637
638     - Always surround these binary operators with a single space on
639       either side: assignment (=), augmented assignment (+=, -= etc.),
640       comparisons (==, <, >, !=, <=, >=, in, not in, is, is not),
641       Booleans (and, or, not).
642
643     - If operators with different priorities are used, consider adding
644       whitespace around the operators with the lowest priorities.
645
646     Okay: i = i + 1
647     Okay: submitted += 1
648     Okay: x = x * 2 - 1
649     Okay: hypot2 = x * x + y * y
650     Okay: c = (a + b) * (a - b)
651     Okay: foo(bar, key='word', *args, **kwargs)
652     Okay: alpha[:-i]
653
654     E225: i=i+1
655     E225: submitted +=1
656     E225: x = x /2 - 1
657     E225: z = x **y
658     E226: c = (a+b) * (a-b)
659     E226: hypot2 = x*x + y*y
660     E227: c = a|b
661     E228: msg = fmt%(errno, errmsg)
662     """
663     parens = 0
664     need_space = False
665     prev_type = tokenize.OP
666     prev_text = prev_end = None
667     for token_type, text, start, end, line in tokens:
668         if token_type in SKIP_COMMENTS:
669             continue
670         if text in ('(', 'lambda'):
671             parens += 1
672         elif text == ')':
673             parens -= 1
674         if need_space:
675             if start != prev_end:
676                 # Found a (probably) needed space
677                 if need_space is not True and not need_space[1]:
678                     yield (need_space[0],
679                            "E225 missing whitespace around operator")
680                 need_space = False
681             elif text == '>' and prev_text in ('<', '-'):
682                 # Tolerate the "<>" operator, even if running Python 3
683                 # Deal with Python 3's annotated return value "->"
684                 pass
685             else:
686                 if need_space is True or need_space[1]:
687                     # A needed trailing space was not found
688                     yield prev_end, "E225 missing whitespace around operator"
689                 elif prev_text != '**':
690                     code, optype = 'E226', 'arithmetic'
691                     if prev_text == '%':
692                         code, optype = 'E228', 'modulo'
693                     elif prev_text not in ARITHMETIC_OP:
694                         code, optype = 'E227', 'bitwise or shift'
695                     yield (need_space[0], "%s missing whitespace "
696                            "around %s operator" % (code, optype))
697                 need_space = False
698         elif token_type == tokenize.OP and prev_end is not None:
699             if text == '=' and parens:
700                 # Allow keyword args or defaults: foo(bar=None).
701                 pass
702             elif text in WS_NEEDED_OPERATORS:
703                 need_space = True
704             elif text in UNARY_OPERATORS:
705                 # Check if the operator is being used as a binary operator
706                 # Allow unary operators: -123, -x, +1.
707                 # Allow argument unpacking: foo(*args, **kwargs).
708                 if (prev_text in '}])' if prev_type == tokenize.OP
709                         else prev_text not in KEYWORDS):
710                     need_space = None
711             elif text in WS_OPTIONAL_OPERATORS:
712                 need_space = None
713
714             if need_space is None:
715                 # Surrounding space is optional, but ensure that
716                 # trailing space matches opening space
717                 need_space = (prev_end, start != prev_end)
718             elif need_space and start == prev_end:
719                 # A needed opening space was not found
720                 yield prev_end, "E225 missing whitespace around operator"
721                 need_space = False
722         prev_type = token_type
723         prev_text = text
724         prev_end = end
725
726
727 def whitespace_around_comma(logical_line):
728     r"""Avoid extraneous whitespace after a comma or a colon.
729
730     Note: these checks are disabled by default
731
732     Okay: a = (1, 2)
733     E241: a = (1,  2)
734     E242: a = (1,\t2)
735     """
736     line = logical_line
737     for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line):
738         found = m.start() + 1
739         if '\t' in m.group():
740             yield found, "E242 tab after '%s'" % m.group()[0]
741         else:
742             yield found, "E241 multiple spaces after '%s'" % m.group()[0]
743
744
745 def whitespace_around_named_parameter_equals(logical_line, tokens):
746     r"""Don't use spaces around the '=' sign in function arguments.
747
748     Don't use spaces around the '=' sign when used to indicate a
749     keyword argument or a default parameter value.
750
751     Okay: def complex(real, imag=0.0):
752     Okay: return magic(r=real, i=imag)
753     Okay: boolean(a == b)
754     Okay: boolean(a != b)
755     Okay: boolean(a <= b)
756     Okay: boolean(a >= b)
757     Okay: def foo(arg: int = 42):
758
759     E251: def complex(real, imag = 0.0):
760     E251: return magic(r = real, i = imag)
761     """
762     parens = 0
763     no_space = False
764     prev_end = None
765     annotated_func_arg = False
766     in_def = logical_line.startswith('def')
767     message = "E251 unexpected spaces around keyword / parameter equals"
768     for token_type, text, start, end, line in tokens:
769         if token_type == tokenize.NL:
770             continue
771         if no_space:
772             no_space = False
773             if start != prev_end:
774                 yield (prev_end, message)
775         if token_type == tokenize.OP:
776             if text == '(':
777                 parens += 1
778             elif text == ')':
779                 parens -= 1
780             elif in_def and text == ':' and parens == 1:
781                 annotated_func_arg = True
782             elif parens and text == ',' and parens == 1:
783                 annotated_func_arg = False
784             elif parens and text == '=' and not annotated_func_arg:
785                 no_space = True
786                 if start != prev_end:
787                     yield (prev_end, message)
788             if not parens:
789                 annotated_func_arg = False
790
791         prev_end = end
792
793
794 def whitespace_before_comment(logical_line, tokens):
795     r"""Separate inline comments by at least two spaces.
796
797     An inline comment is a comment on the same line as a statement.  Inline
798     comments should be separated by at least two spaces from the statement.
799     They should start with a # and a single space.
800
801     Each line of a block comment starts with a # and a single space
802     (unless it is indented text inside the comment).
803
804     Okay: x = x + 1  # Increment x
805     Okay: x = x + 1    # Increment x
806     Okay: # Block comment
807     E261: x = x + 1 # Increment x
808     E262: x = x + 1  #Increment x
809     E262: x = x + 1  #  Increment x
810     E265: #Block comment
811     E266: ### Block comment
812     """
813     prev_end = (0, 0)
814     for token_type, text, start, end, line in tokens:
815         if token_type == tokenize.COMMENT:
816             inline_comment = line[:start[1]].strip()
817             if inline_comment:
818                 if prev_end[0] == start[0] and start[1] < prev_end[1] + 2:
819                     yield (prev_end,
820                            "E261 at least two spaces before inline comment")
821             symbol, sp, comment = text.partition(' ')
822             bad_prefix = symbol not in '#:' and (symbol.lstrip('#')[:1] or '#')
823             if inline_comment:
824                 if bad_prefix or comment[:1] in WHITESPACE:
825                     yield start, "E262 inline comment should start with '# '"
826             elif bad_prefix and (bad_prefix != '!' or start[0] > 1):
827                 if bad_prefix != '#':
828                     yield start, "E265 block comment should start with '# '"
829                 elif comment:
830                     yield start, "E266 too many leading '#' for block comment"
831         elif token_type != tokenize.NL:
832             prev_end = end
833
834
835 def imports_on_separate_lines(logical_line):
836     r"""Imports should usually be on separate lines.
837
838     Okay: import os\nimport sys
839     E401: import sys, os
840
841     Okay: from subprocess import Popen, PIPE
842     Okay: from myclas import MyClass
843     Okay: from foo.bar.yourclass import YourClass
844     Okay: import myclass
845     Okay: import foo.bar.yourclass
846     """
847     line = logical_line
848     if line.startswith('import '):
849         found = line.find(',')
850         if -1 < found and ';' not in line[:found]:
851             yield found, "E401 multiple imports on one line"
852
853
854 def module_imports_on_top_of_file(
855         logical_line, indent_level, checker_state, noqa):
856     r"""Imports are always put at the top of the file, just after any module
857     comments and docstrings, and before module globals and constants.
858
859     Okay: import os
860     Okay: # this is a comment\nimport os
861     Okay: '''this is a module docstring'''\nimport os
862     Okay: r'''this is a module docstring'''\nimport os
863     Okay: try:\n    import x\nexcept:\n    pass\nelse:\n    pass\nimport y
864     Okay: try:\n    import x\nexcept:\n    pass\nfinally:\n    pass\nimport y
865     E402: a=1\nimport os
866     E402: 'One string'\n"Two string"\nimport os
867     E402: a=1\nfrom sys import x
868
869     Okay: if x:\n    import os
870     """
871     def is_string_literal(line):
872         if line[0] in 'uUbB':
873             line = line[1:]
874         if line and line[0] in 'rR':
875             line = line[1:]
876         return line and (line[0] == '"' or line[0] == "'")
877
878     allowed_try_keywords = ('try', 'except', 'else', 'finally')
879
880     if indent_level:  # Allow imports in conditional statements or functions
881         return
882     if not logical_line:  # Allow empty lines or comments
883         return
884     if noqa:
885         return
886     line = logical_line
887     if line.startswith('import ') or line.startswith('from '):
888         if checker_state.get('seen_non_imports', False):
889             yield 0, "E402 module level import not at top of file"
890     elif any(line.startswith(kw) for kw in allowed_try_keywords):
891         # Allow try, except, else, finally keywords intermixed with imports in
892         # order to support conditional importing
893         return
894     elif is_string_literal(line):
895         # The first literal is a docstring, allow it. Otherwise, report error.
896         if checker_state.get('seen_docstring', False):
897             checker_state['seen_non_imports'] = True
898         else:
899             checker_state['seen_docstring'] = True
900     else:
901         checker_state['seen_non_imports'] = True
902
903
904 def compound_statements(logical_line):
905     r"""Compound statements (on the same line) are generally discouraged.
906
907     While sometimes it's okay to put an if/for/while with a small body
908     on the same line, never do this for multi-clause statements.
909     Also avoid folding such long lines!
910
911     Always use a def statement instead of an assignment statement that
912     binds a lambda expression directly to a name.
913
914     Okay: if foo == 'blah':\n    do_blah_thing()
915     Okay: do_one()
916     Okay: do_two()
917     Okay: do_three()
918
919     E701: if foo == 'blah': do_blah_thing()
920     E701: for x in lst: total += x
921     E701: while t < 10: t = delay()
922     E701: if foo == 'blah': do_blah_thing()
923     E701: else: do_non_blah_thing()
924     E701: try: something()
925     E701: finally: cleanup()
926     E701: if foo == 'blah': one(); two(); three()
927     E702: do_one(); do_two(); do_three()
928     E703: do_four();  # useless semicolon
929     E704: def f(x): return 2*x
930     E731: f = lambda x: 2*x
931     """
932     line = logical_line
933     last_char = len(line) - 1
934     found = line.find(':')
935     while -1 < found < last_char:
936         before = line[:found]
937         if ((before.count('{') <= before.count('}') and   # {'a': 1} (dict)
938              before.count('[') <= before.count(']') and   # [1:2] (slice)
939              before.count('(') <= before.count(')'))):    # (annotation)
940             lambda_kw = LAMBDA_REGEX.search(before)
941             if lambda_kw:
942                 before = line[:lambda_kw.start()].rstrip()
943                 if before[-1:] == '=' and isidentifier(before[:-1].strip()):
944                     yield 0, ("E731 do not assign a lambda expression, use a "
945                               "def")
946                 break
947             if before.startswith('def '):
948                 yield 0, "E704 multiple statements on one line (def)"
949             else:
950                 yield found, "E701 multiple statements on one line (colon)"
951         found = line.find(':', found + 1)
952     found = line.find(';')
953     while -1 < found:
954         if found < last_char:
955             yield found, "E702 multiple statements on one line (semicolon)"
956         else:
957             yield found, "E703 statement ends with a semicolon"
958         found = line.find(';', found + 1)
959
960
961 def explicit_line_join(logical_line, tokens):
962     r"""Avoid explicit line join between brackets.
963
964     The preferred way of wrapping long lines is by using Python's implied line
965     continuation inside parentheses, brackets and braces.  Long lines can be
966     broken over multiple lines by wrapping expressions in parentheses.  These
967     should be used in preference to using a backslash for line continuation.
968
969     E502: aaa = [123, \\n       123]
970     E502: aaa = ("bbb " \\n       "ccc")
971
972     Okay: aaa = [123,\n       123]
973     Okay: aaa = ("bbb "\n       "ccc")
974     Okay: aaa = "bbb " \\n    "ccc"
975     """
976     prev_start = prev_end = parens = 0
977     for token_type, text, start, end, line in tokens:
978         if start[0] != prev_start and parens and backslash:
979             yield backslash, "E502 the backslash is redundant between brackets"
980         if end[0] != prev_end:
981             if line.rstrip('\r\n').endswith('\\'):
982                 backslash = (end[0], len(line.splitlines()[-1]) - 1)
983             else:
984                 backslash = None
985             prev_start = prev_end = end[0]
986         else:
987             prev_start = start[0]
988         if token_type == tokenize.OP:
989             if text in '([{':
990                 parens += 1
991             elif text in ')]}':
992                 parens -= 1
993
994
995 def comparison_to_singleton(logical_line, noqa):
996     r"""Comparison to singletons should use "is" or "is not".
997
998     Comparisons to singletons like None should always be done
999     with "is" or "is not", never the equality operators.
1000
1001     Okay: if arg is not None:
1002     E711: if arg != None:
1003     E711: if None == arg:
1004     E712: if arg == True:
1005     E712: if False == arg:
1006
1007     Also, beware of writing if x when you really mean if x is not None --
1008     e.g. when testing whether a variable or argument that defaults to None was
1009     set to some other value.  The other value might have a type (such as a
1010     container) that could be false in a boolean context!
1011     """
1012     match = not noqa and COMPARE_SINGLETON_REGEX.search(logical_line)
1013     if match:
1014         singleton = match.group(1) or match.group(3)
1015         same = (match.group(2) == '==')
1016
1017         msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton)
1018         if singleton in ('None',):
1019             code = 'E711'
1020         else:
1021             code = 'E712'
1022             nonzero = ((singleton == 'True' and same) or
1023                        (singleton == 'False' and not same))
1024             msg += " or 'if %scond:'" % ('' if nonzero else 'not ')
1025         yield match.start(2), ("%s comparison to %s should be %s" %
1026                                (code, singleton, msg))
1027
1028
1029 def comparison_negative(logical_line):
1030     r"""Negative comparison should be done using "not in" and "is not".
1031
1032     Okay: if x not in y:\n    pass
1033     Okay: assert (X in Y or X is Z)
1034     Okay: if not (X in Y):\n    pass
1035     Okay: zz = x is not y
1036     E713: Z = not X in Y
1037     E713: if not X.B in Y:\n    pass
1038     E714: if not X is Y:\n    pass
1039     E714: Z = not X.B is Y
1040     """
1041     match = COMPARE_NEGATIVE_REGEX.search(logical_line)
1042     if match:
1043         pos = match.start(1)
1044         if match.group(2) == 'in':
1045             yield pos, "E713 test for membership should be 'not in'"
1046         else:
1047             yield pos, "E714 test for object identity should be 'is not'"
1048
1049
1050 def comparison_type(logical_line):
1051     r"""Object type comparisons should always use isinstance().
1052
1053     Do not compare types directly.
1054
1055     Okay: if isinstance(obj, int):
1056     E721: if type(obj) is type(1):
1057
1058     When checking if an object is a string, keep in mind that it might be a
1059     unicode string too! In Python 2.3, str and unicode have a common base
1060     class, basestring, so you can do:
1061
1062     Okay: if isinstance(obj, basestring):
1063     Okay: if type(a1) is type(b1):
1064     """
1065     match = COMPARE_TYPE_REGEX.search(logical_line)
1066     if match:
1067         inst = match.group(1)
1068         if inst and isidentifier(inst) and inst not in SINGLETONS:
1069             return  # Allow comparison for types which are not obvious
1070         yield match.start(), "E721 do not compare types, use 'isinstance()'"
1071
1072
1073 def python_3000_has_key(logical_line, noqa):
1074     r"""The {}.has_key() method is removed in Python 3: use the 'in' operator.
1075
1076     Okay: if "alph" in d:\n    print d["alph"]
1077     W601: assert d.has_key('alph')
1078     """
1079     pos = logical_line.find('.has_key(')
1080     if pos > -1 and not noqa:
1081         yield pos, "W601 .has_key() is deprecated, use 'in'"
1082
1083
1084 def python_3000_raise_comma(logical_line):
1085     r"""When raising an exception, use "raise ValueError('message')".
1086
1087     The older form is removed in Python 3.
1088
1089     Okay: raise DummyError("Message")
1090     W602: raise DummyError, "Message"
1091     """
1092     match = RAISE_COMMA_REGEX.match(logical_line)
1093     if match and not RERAISE_COMMA_REGEX.match(logical_line):
1094         yield match.end() - 1, "W602 deprecated form of raising exception"
1095
1096
1097 def python_3000_not_equal(logical_line):
1098     r"""New code should always use != instead of <>.
1099
1100     The older syntax is removed in Python 3.
1101
1102     Okay: if a != 'no':
1103     W603: if a <> 'no':
1104     """
1105     pos = logical_line.find('<>')
1106     if pos > -1:
1107         yield pos, "W603 '<>' is deprecated, use '!='"
1108
1109
1110 def python_3000_backticks(logical_line):
1111     r"""Backticks are removed in Python 3: use repr() instead.
1112
1113     Okay: val = repr(1 + 2)
1114     W604: val = `1 + 2`
1115     """
1116     pos = logical_line.find('`')
1117     if pos > -1:
1118         yield pos, "W604 backticks are deprecated, use 'repr()'"
1119
1120
1121 ##############################################################################
1122 # Helper functions
1123 ##############################################################################
1124
1125
1126 if '' == ''.encode():
1127     # Python 2: implicit encoding.
1128     def readlines(filename):
1129         """Read the source code."""
1130         with open(filename, 'rU') as f:
1131             return f.readlines()
1132     isidentifier = re.compile(r'[a-zA-Z_]\w*$').match
1133     stdin_get_value = sys.stdin.read
1134 else:
1135     # Python 3
1136     def readlines(filename):
1137         """Read the source code."""
1138         try:
1139             with open(filename, 'rb') as f:
1140                 (coding, lines) = tokenize.detect_encoding(f.readline)
1141                 f = TextIOWrapper(f, coding, line_buffering=True)
1142                 return [l.decode(coding) for l in lines] + f.readlines()
1143         except (LookupError, SyntaxError, UnicodeError):
1144             # Fall back if file encoding is improperly declared
1145             with open(filename, encoding='latin-1') as f:
1146                 return f.readlines()
1147     isidentifier = str.isidentifier
1148
1149     def stdin_get_value():
1150         return TextIOWrapper(sys.stdin.buffer, errors='ignore').read()
1151 noqa = re.compile(r'# no(?:qa|pep8)\b', re.I).search
1152
1153
1154 def expand_indent(line):
1155     r"""Return the amount of indentation.
1156
1157     Tabs are expanded to the next multiple of 8.
1158
1159     >>> expand_indent('    ')
1160     4
1161     >>> expand_indent('\t')
1162     8
1163     >>> expand_indent('       \t')
1164     8
1165     >>> expand_indent('        \t')
1166     16
1167     """
1168     if '\t' not in line:
1169         return len(line) - len(line.lstrip())
1170     result = 0
1171     for char in line:
1172         if char == '\t':
1173             result = result // 8 * 8 + 8
1174         elif char == ' ':
1175             result += 1
1176         else:
1177             break
1178     return result
1179
1180
1181 def mute_string(text):
1182     """Replace contents with 'xxx' to prevent syntax matching.
1183
1184     >>> mute_string('"abc"')
1185     '"xxx"'
1186     >>> mute_string("'''abc'''")
1187     "'''xxx'''"
1188     >>> mute_string("r'abc'")
1189     "r'xxx'"
1190     """
1191     # String modifiers (e.g. u or r)
1192     start = text.index(text[-1]) + 1
1193     end = len(text) - 1
1194     # Triple quotes
1195     if text[-3:] in ('"""', "'''"):
1196         start += 2
1197         end -= 2
1198     return text[:start] + 'x' * (end - start) + text[end:]
1199
1200
1201 def parse_udiff(diff, patterns=None, parent='.'):
1202     """Return a dictionary of matching lines."""
1203     # For each file of the diff, the entry key is the filename,
1204     # and the value is a set of row numbers to consider.
1205     rv = {}
1206     path = nrows = None
1207     for line in diff.splitlines():
1208         if nrows:
1209             if line[:1] != '-':
1210                 nrows -= 1
1211             continue
1212         if line[:3] == '@@ ':
1213             hunk_match = HUNK_REGEX.match(line)
1214             (row, nrows) = [int(g or '1') for g in hunk_match.groups()]
1215             rv[path].update(range(row, row + nrows))
1216         elif line[:3] == '+++':
1217             path = line[4:].split('\t', 1)[0]
1218             if path[:2] == 'b/':
1219                 path = path[2:]
1220             rv[path] = set()
1221     return dict([(os.path.join(parent, path), rows)
1222                  for (path, rows) in rv.items()
1223                  if rows and filename_match(path, patterns)])
1224
1225
1226 def normalize_paths(value, parent=os.curdir):
1227     """Parse a comma-separated list of paths.
1228
1229     Return a list of absolute paths.
1230     """
1231     if not value:
1232         return []
1233     if isinstance(value, list):
1234         return value
1235     paths = []
1236     for path in value.split(','):
1237         path = path.strip()
1238         if '/' in path:
1239             path = os.path.abspath(os.path.join(parent, path))
1240         paths.append(path.rstrip('/'))
1241     return paths
1242
1243
1244 def filename_match(filename, patterns, default=True):
1245     """Check if patterns contains a pattern that matches filename.
1246
1247     If patterns is unspecified, this always returns True.
1248     """
1249     if not patterns:
1250         return default
1251     return any(fnmatch(filename, pattern) for pattern in patterns)
1252
1253
1254 def _is_eol_token(token):
1255     return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n'
1256 if COMMENT_WITH_NL:
1257     def _is_eol_token(token, _eol_token=_is_eol_token):
1258         return _eol_token(token) or (token[0] == tokenize.COMMENT and
1259                                      token[1] == token[4])
1260
1261 ##############################################################################
1262 # Framework to run all checks
1263 ##############################################################################
1264
1265
1266 _checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}}
1267
1268
1269 def register_check(check, codes=None):
1270     """Register a new check object."""
1271     def _add_check(check, kind, codes, args):
1272         if check in _checks[kind]:
1273             _checks[kind][check][0].extend(codes or [])
1274         else:
1275             _checks[kind][check] = (codes or [''], args)
1276     if inspect.isfunction(check):
1277         args = inspect.getargspec(check)[0]
1278         if args and args[0] in ('physical_line', 'logical_line'):
1279             if codes is None:
1280                 codes = ERRORCODE_REGEX.findall(check.__doc__ or '')
1281             _add_check(check, args[0], codes, args)
1282     elif inspect.isclass(check):
1283         if inspect.getargspec(check.__init__)[0][:2] == ['self', 'tree']:
1284             _add_check(check, 'tree', codes, None)
1285
1286
1287 def init_checks_registry():
1288     """Register all globally visible functions.
1289
1290     The first argument name is either 'physical_line' or 'logical_line'.
1291     """
1292     mod = inspect.getmodule(register_check)
1293     for (name, function) in inspect.getmembers(mod, inspect.isfunction):
1294         register_check(function)
1295 init_checks_registry()
1296
1297
1298 class Checker(object):
1299     """Load a Python source file, tokenize it, check coding style."""
1300
1301     def __init__(self, filename=None, lines=None,
1302                  options=None, report=None, **kwargs):
1303         if options is None:
1304             options = StyleGuide(kwargs).options
1305         else:
1306             assert not kwargs
1307         self._io_error = None
1308         self._physical_checks = options.physical_checks
1309         self._logical_checks = options.logical_checks
1310         self._ast_checks = options.ast_checks
1311         self.max_line_length = options.max_line_length
1312         self.multiline = False  # in a multiline string?
1313         self.hang_closing = options.hang_closing
1314         self.verbose = options.verbose
1315         self.filename = filename
1316         # Dictionary where a checker can store its custom state.
1317         self._checker_states = {}
1318         if filename is None:
1319             self.filename = 'stdin'
1320             self.lines = lines or []
1321         elif filename == '-':
1322             self.filename = 'stdin'
1323             self.lines = stdin_get_value().splitlines(True)
1324         elif lines is None:
1325             try:
1326                 self.lines = readlines(filename)
1327             except IOError:
1328                 (exc_type, exc) = sys.exc_info()[:2]
1329                 self._io_error = '%s: %s' % (exc_type.__name__, exc)
1330                 self.lines = []
1331         else:
1332             self.lines = lines
1333         if self.lines:
1334             ord0 = ord(self.lines[0][0])
1335             if ord0 in (0xef, 0xfeff):  # Strip the UTF-8 BOM
1336                 if ord0 == 0xfeff:
1337                     self.lines[0] = self.lines[0][1:]
1338                 elif self.lines[0][:3] == '\xef\xbb\xbf':
1339                     self.lines[0] = self.lines[0][3:]
1340         self.report = report or options.report
1341         self.report_error = self.report.error
1342
1343     def report_invalid_syntax(self):
1344         """Check if the syntax is valid."""
1345         (exc_type, exc) = sys.exc_info()[:2]
1346         if len(exc.args) > 1:
1347             offset = exc.args[1]
1348             if len(offset) > 2:
1349                 offset = offset[1:3]
1350         else:
1351             offset = (1, 0)
1352         self.report_error(offset[0], offset[1] or 0,
1353                           'E901 %s: %s' % (exc_type.__name__, exc.args[0]),
1354                           self.report_invalid_syntax)
1355
1356     def readline(self):
1357         """Get the next line from the input buffer."""
1358         if self.line_number >= self.total_lines:
1359             return ''
1360         line = self.lines[self.line_number]
1361         self.line_number += 1
1362         if self.indent_char is None and line[:1] in WHITESPACE:
1363             self.indent_char = line[0]
1364         return line
1365
1366     def run_check(self, check, argument_names):
1367         """Run a check plugin."""
1368         arguments = []
1369         for name in argument_names:
1370             arguments.append(getattr(self, name))
1371         return check(*arguments)
1372
1373     def init_checker_state(self, name, argument_names):
1374         """ Prepares a custom state for the specific checker plugin."""
1375         if 'checker_state' in argument_names:
1376             self.checker_state = self._checker_states.setdefault(name, {})
1377
1378     def check_physical(self, line):
1379         """Run all physical checks on a raw input line."""
1380         self.physical_line = line
1381         for name, check, argument_names in self._physical_checks:
1382             self.init_checker_state(name, argument_names)
1383             result = self.run_check(check, argument_names)
1384             if result is not None:
1385                 (offset, text) = result
1386                 self.report_error(self.line_number, offset, text, check)
1387                 if text[:4] == 'E101':
1388                     self.indent_char = line[0]
1389
1390     def build_tokens_line(self):
1391         """Build a logical line from tokens."""
1392         logical = []
1393         comments = []
1394         length = 0
1395         prev_row = prev_col = mapping = None
1396         for token_type, text, start, end, line in self.tokens:
1397             if token_type in SKIP_TOKENS:
1398                 continue
1399             if not mapping:
1400                 mapping = [(0, start)]
1401             if token_type == tokenize.COMMENT:
1402                 comments.append(text)
1403                 continue
1404             if token_type == tokenize.STRING:
1405                 text = mute_string(text)
1406             if prev_row:
1407                 (start_row, start_col) = start
1408                 if prev_row != start_row:    # different row
1409                     prev_text = self.lines[prev_row - 1][prev_col - 1]
1410                     if prev_text == ',' or (prev_text not in '{[('
1411                                             and text not in '}])'):
1412                         text = ' ' + text
1413                 elif prev_col != start_col:  # different column
1414                     text = line[prev_col:start_col] + text
1415             logical.append(text)
1416             length += len(text)
1417             mapping.append((length, end))
1418             (prev_row, prev_col) = end
1419         self.logical_line = ''.join(logical)
1420         self.noqa = comments and noqa(''.join(comments))
1421         return mapping
1422
1423     def check_logical(self):
1424         """Build a line from tokens and run all logical checks on it."""
1425         self.report.increment_logical_line()
1426         mapping = self.build_tokens_line()
1427
1428         if not mapping:
1429             return
1430
1431         (start_row, start_col) = mapping[0][1]
1432         start_line = self.lines[start_row - 1]
1433         self.indent_level = expand_indent(start_line[:start_col])
1434         if self.blank_before < self.blank_lines:
1435             self.blank_before = self.blank_lines
1436         if self.verbose >= 2:
1437             print(self.logical_line[:80].rstrip())
1438         for name, check, argument_names in self._logical_checks:
1439             if self.verbose >= 4:
1440                 print('   ' + name)
1441             self.init_checker_state(name, argument_names)
1442             for offset, text in self.run_check(check, argument_names) or ():
1443                 if not isinstance(offset, tuple):
1444                     for token_offset, pos in mapping:
1445                         if offset <= token_offset:
1446                             break
1447                     offset = (pos[0], pos[1] + offset - token_offset)
1448                 self.report_error(offset[0], offset[1], text, check)
1449         if self.logical_line:
1450             self.previous_indent_level = self.indent_level
1451             self.previous_logical = self.logical_line
1452         self.blank_lines = 0
1453         self.tokens = []
1454
1455     def check_ast(self):
1456         """Build the file's AST and run all AST checks."""
1457         try:
1458             tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST)
1459         except (SyntaxError, TypeError):
1460             return self.report_invalid_syntax()
1461         for name, cls, __ in self._ast_checks:
1462             checker = cls(tree, self.filename)
1463             for lineno, offset, text, check in checker.run():
1464                 if not self.lines or not noqa(self.lines[lineno - 1]):
1465                     self.report_error(lineno, offset, text, check)
1466
1467     def generate_tokens(self):
1468         """Tokenize the file, run physical line checks and yield tokens."""
1469         if self._io_error:
1470             self.report_error(1, 0, 'E902 %s' % self._io_error, readlines)
1471         tokengen = tokenize.generate_tokens(self.readline)
1472         try:
1473             for token in tokengen:
1474                 if token[2][0] > self.total_lines:
1475                     return
1476                 self.maybe_check_physical(token)
1477                 yield token
1478         except (SyntaxError, tokenize.TokenError):
1479             self.report_invalid_syntax()
1480
1481     def maybe_check_physical(self, token):
1482         """If appropriate (based on token), check current physical line(s)."""
1483         # Called after every token, but act only on end of line.
1484         if _is_eol_token(token):
1485             # Obviously, a newline token ends a single physical line.
1486             self.check_physical(token[4])
1487         elif token[0] == tokenize.STRING and '\n' in token[1]:
1488             # Less obviously, a string that contains newlines is a
1489             # multiline string, either triple-quoted or with internal
1490             # newlines backslash-escaped. Check every physical line in the
1491             # string *except* for the last one: its newline is outside of
1492             # the multiline string, so we consider it a regular physical
1493             # line, and will check it like any other physical line.
1494             #
1495             # Subtleties:
1496             # - we don't *completely* ignore the last line; if it contains
1497             #   the magical "# noqa" comment, we disable all physical
1498             #   checks for the entire multiline string
1499             # - have to wind self.line_number back because initially it
1500             #   points to the last line of the string, and we want
1501             #   check_physical() to give accurate feedback
1502             if noqa(token[4]):
1503                 return
1504             self.multiline = True
1505             self.line_number = token[2][0]
1506             for line in token[1].split('\n')[:-1]:
1507                 self.check_physical(line + '\n')
1508                 self.line_number += 1
1509             self.multiline = False
1510
1511     def check_all(self, expected=None, line_offset=0):
1512         """Run all checks on the input file."""
1513         self.report.init_file(self.filename, self.lines, expected, line_offset)
1514         self.total_lines = len(self.lines)
1515         if self._ast_checks:
1516             self.check_ast()
1517         self.line_number = 0
1518         self.indent_char = None
1519         self.indent_level = self.previous_indent_level = 0
1520         self.previous_logical = ''
1521         self.tokens = []
1522         self.blank_lines = self.blank_before = 0
1523         parens = 0
1524         for token in self.generate_tokens():
1525             self.tokens.append(token)
1526             token_type, text = token[0:2]
1527             if self.verbose >= 3:
1528                 if token[2][0] == token[3][0]:
1529                     pos = '[%s:%s]' % (token[2][1] or '', token[3][1])
1530                 else:
1531                     pos = 'l.%s' % token[3][0]
1532                 print('l.%s\t%s\t%s\t%r' %
1533                       (token[2][0], pos, tokenize.tok_name[token[0]], text))
1534             if token_type == tokenize.OP:
1535                 if text in '([{':
1536                     parens += 1
1537                 elif text in '}])':
1538                     parens -= 1
1539             elif not parens:
1540                 if token_type in NEWLINE:
1541                     if token_type == tokenize.NEWLINE:
1542                         self.check_logical()
1543                         self.blank_before = 0
1544                     elif len(self.tokens) == 1:
1545                         # The physical line contains only this token.
1546                         self.blank_lines += 1
1547                         del self.tokens[0]
1548                     else:
1549                         self.check_logical()
1550                 elif COMMENT_WITH_NL and token_type == tokenize.COMMENT:
1551                     if len(self.tokens) == 1:
1552                         # The comment also ends a physical line
1553                         token = list(token)
1554                         token[1] = text.rstrip('\r\n')
1555                         token[3] = (token[2][0], token[2][1] + len(token[1]))
1556                         self.tokens = [tuple(token)]
1557                         self.check_logical()
1558         if self.tokens:
1559             self.check_physical(self.lines[-1])
1560             self.check_logical()
1561         return self.report.get_file_results()
1562
1563
1564 class BaseReport(object):
1565     """Collect the results of the checks."""
1566
1567     print_filename = False
1568
1569     def __init__(self, options):
1570         self._benchmark_keys = options.benchmark_keys
1571         self._ignore_code = options.ignore_code
1572         # Results
1573         self.elapsed = 0
1574         self.total_errors = 0
1575         self.counters = dict.fromkeys(self._benchmark_keys, 0)
1576         self.messages = {}
1577
1578     def start(self):
1579         """Start the timer."""
1580         self._start_time = time.time()
1581
1582     def stop(self):
1583         """Stop the timer."""
1584         self.elapsed = time.time() - self._start_time
1585
1586     def init_file(self, filename, lines, expected, line_offset):
1587         """Signal a new file."""
1588         self.filename = filename
1589         self.lines = lines
1590         self.expected = expected or ()
1591         self.line_offset = line_offset
1592         self.file_errors = 0
1593         self.counters['files'] += 1
1594         self.counters['physical lines'] += len(lines)
1595
1596     def increment_logical_line(self):
1597         """Signal a new logical line."""
1598         self.counters['logical lines'] += 1
1599
1600     def error(self, line_number, offset, text, check):
1601         """Report an error, according to options."""
1602         code = text[:4]
1603         if self._ignore_code(code):
1604             return
1605         if code in self.counters:
1606             self.counters[code] += 1
1607         else:
1608             self.counters[code] = 1
1609             self.messages[code] = text[5:]
1610         # Don't care about expected errors or warnings
1611         if code in self.expected:
1612             return
1613         if self.print_filename and not self.file_errors:
1614             print(self.filename)
1615         self.file_errors += 1
1616         self.total_errors += 1
1617         return code
1618
1619     def get_file_results(self):
1620         """Return the count of errors and warnings for this file."""
1621         return self.file_errors
1622
1623     def get_count(self, prefix=''):
1624         """Return the total count of errors and warnings."""
1625         return sum([self.counters[key]
1626                     for key in self.messages if key.startswith(prefix)])
1627
1628     def get_statistics(self, prefix=''):
1629         """Get statistics for message codes that start with the prefix.
1630
1631         prefix='' matches all errors and warnings
1632         prefix='E' matches all errors
1633         prefix='W' matches all warnings
1634         prefix='E4' matches all errors that have to do with imports
1635         """
1636         return ['%-7s %s %s' % (self.counters[key], key, self.messages[key])
1637                 for key in sorted(self.messages) if key.startswith(prefix)]
1638
1639     def print_statistics(self, prefix=''):
1640         """Print overall statistics (number of errors and warnings)."""
1641         for line in self.get_statistics(prefix):
1642             print(line)
1643
1644     def print_benchmark(self):
1645         """Print benchmark numbers."""
1646         print('%-7.2f %s' % (self.elapsed, 'seconds elapsed'))
1647         if self.elapsed:
1648             for key in self._benchmark_keys:
1649                 print('%-7d %s per second (%d total)' %
1650                       (self.counters[key] / self.elapsed, key,
1651                        self.counters[key]))
1652
1653
1654 class FileReport(BaseReport):
1655     """Collect the results of the checks and print only the filenames."""
1656     print_filename = True
1657
1658
1659 class StandardReport(BaseReport):
1660     """Collect and print the results of the checks."""
1661
1662     def __init__(self, options):
1663         super(StandardReport, self).__init__(options)
1664         self._fmt = REPORT_FORMAT.get(options.format.lower(),
1665                                       options.format)
1666         self._repeat = options.repeat
1667         self._show_source = options.show_source
1668         self._show_pep8 = options.show_pep8
1669
1670     def init_file(self, filename, lines, expected, line_offset):
1671         """Signal a new file."""
1672         self._deferred_print = []
1673         return super(StandardReport, self).init_file(
1674             filename, lines, expected, line_offset)
1675
1676     def error(self, line_number, offset, text, check):
1677         """Report an error, according to options."""
1678         code = super(StandardReport, self).error(line_number, offset,
1679                                                  text, check)
1680         if code and (self.counters[code] == 1 or self._repeat):
1681             self._deferred_print.append(
1682                 (line_number, offset, code, text[5:], check.__doc__))
1683         return code
1684
1685     def get_file_results(self):
1686         """Print the result and return the overall count for this file."""
1687         self._deferred_print.sort()
1688         for line_number, offset, code, text, doc in self._deferred_print:
1689             print(self._fmt % {
1690                 'path': self.filename,
1691                 'row': self.line_offset + line_number, 'col': offset + 1,
1692                 'code': code, 'text': text,
1693             })
1694             if self._show_source:
1695                 if line_number > len(self.lines):
1696                     line = ''
1697                 else:
1698                     line = self.lines[line_number - 1]
1699                 print(line.rstrip())
1700                 print(re.sub(r'\S', ' ', line[:offset]) + '^')
1701             if self._show_pep8 and doc:
1702                 print('    ' + doc.strip())
1703         return self.file_errors
1704
1705
1706 class DiffReport(StandardReport):
1707     """Collect and print the results for the changed lines only."""
1708
1709     def __init__(self, options):
1710         super(DiffReport, self).__init__(options)
1711         self._selected = options.selected_lines
1712
1713     def error(self, line_number, offset, text, check):
1714         if line_number not in self._selected[self.filename]:
1715             return
1716         return super(DiffReport, self).error(line_number, offset, text, check)
1717
1718
1719 class StyleGuide(object):
1720     """Initialize a PEP-8 instance with few options."""
1721
1722     def __init__(self, *args, **kwargs):
1723         # build options from the command line
1724         self.checker_class = kwargs.pop('checker_class', Checker)
1725         parse_argv = kwargs.pop('parse_argv', False)
1726         config_file = kwargs.pop('config_file', None)
1727         parser = kwargs.pop('parser', None)
1728         # build options from dict
1729         options_dict = dict(*args, **kwargs)
1730         arglist = None if parse_argv else options_dict.get('paths', None)
1731         options, self.paths = process_options(
1732             arglist, parse_argv, config_file, parser)
1733         if options_dict:
1734             options.__dict__.update(options_dict)
1735             if 'paths' in options_dict:
1736                 self.paths = options_dict['paths']
1737
1738         self.runner = self.input_file
1739         self.options = options
1740
1741         if not options.reporter:
1742             options.reporter = BaseReport if options.quiet else StandardReport
1743
1744         options.select = tuple(options.select or ())
1745         if not (options.select or options.ignore or
1746                 options.testsuite or options.doctest) and DEFAULT_IGNORE:
1747             # The default choice: ignore controversial checks
1748             options.ignore = tuple(DEFAULT_IGNORE.split(','))
1749         else:
1750             # Ignore all checks which are not explicitly selected
1751             options.ignore = ('',) if options.select else tuple(options.ignore)
1752         options.benchmark_keys = BENCHMARK_KEYS[:]
1753         options.ignore_code = self.ignore_code
1754         options.physical_checks = self.get_checks('physical_line')
1755         options.logical_checks = self.get_checks('logical_line')
1756         options.ast_checks = self.get_checks('tree')
1757         self.init_report()
1758
1759     def init_report(self, reporter=None):
1760         """Initialize the report instance."""
1761         self.options.report = (reporter or self.options.reporter)(self.options)
1762         return self.options.report
1763
1764     def check_files(self, paths=None):
1765         """Run all checks on the paths."""
1766         if paths is None:
1767             paths = self.paths
1768         report = self.options.report
1769         runner = self.runner
1770         report.start()
1771         try:
1772             for path in paths:
1773                 if os.path.isdir(path):
1774                     self.input_dir(path)
1775                 elif not self.excluded(path):
1776                     runner(path)
1777         except KeyboardInterrupt:
1778             print('... stopped')
1779         report.stop()
1780         return report
1781
1782     def input_file(self, filename, lines=None, expected=None, line_offset=0):
1783         """Run all checks on a Python source file."""
1784         if self.options.verbose:
1785             print('checking %s' % filename)
1786         fchecker = self.checker_class(
1787             filename, lines=lines, options=self.options)
1788         return fchecker.check_all(expected=expected, line_offset=line_offset)
1789
1790     def input_dir(self, dirname):
1791         """Check all files in this directory and all subdirectories."""
1792         dirname = dirname.rstrip('/')
1793         if self.excluded(dirname):
1794             return 0
1795         counters = self.options.report.counters
1796         verbose = self.options.verbose
1797         filepatterns = self.options.filename
1798         runner = self.runner
1799         for root, dirs, files in os.walk(dirname):
1800             if verbose:
1801                 print('directory ' + root)
1802             counters['directories'] += 1
1803             for subdir in sorted(dirs):
1804                 if self.excluded(subdir, root):
1805                     dirs.remove(subdir)
1806             for filename in sorted(files):
1807                 # contain a pattern that matches?
1808                 if ((filename_match(filename, filepatterns) and
1809                      not self.excluded(filename, root))):
1810                     runner(os.path.join(root, filename))
1811
1812     def excluded(self, filename, parent=None):
1813         """Check if the file should be excluded.
1814
1815         Check if 'options.exclude' contains a pattern that matches filename.
1816         """
1817         if not self.options.exclude:
1818             return False
1819         basename = os.path.basename(filename)
1820         if filename_match(basename, self.options.exclude):
1821             return True
1822         if parent:
1823             filename = os.path.join(parent, filename)
1824         filename = os.path.abspath(filename)
1825         return filename_match(filename, self.options.exclude)
1826
1827     def ignore_code(self, code):
1828         """Check if the error code should be ignored.
1829
1830         If 'options.select' contains a prefix of the error code,
1831         return False.  Else, if 'options.ignore' contains a prefix of
1832         the error code, return True.
1833         """
1834         if len(code) < 4 and any(s.startswith(code)
1835                                  for s in self.options.select):
1836             return False
1837         return (code.startswith(self.options.ignore) and
1838                 not code.startswith(self.options.select))
1839
1840     def get_checks(self, argument_name):
1841         """Get all the checks for this category.
1842
1843         Find all globally visible functions where the first argument name
1844         starts with argument_name and which contain selected tests.
1845         """
1846         checks = []
1847         for check, attrs in _checks[argument_name].items():
1848             (codes, args) = attrs
1849             if any(not (code and self.ignore_code(code)) for code in codes):
1850                 checks.append((check.__name__, check, args))
1851         return sorted(checks)
1852
1853
1854 def get_parser(prog='pep8', version=__version__):
1855     parser = OptionParser(prog=prog, version=version,
1856                           usage="%prog [options] input ...")
1857     parser.config_options = [
1858         'exclude', 'filename', 'select', 'ignore', 'max-line-length',
1859         'hang-closing', 'count', 'format', 'quiet', 'show-pep8',
1860         'show-source', 'statistics', 'verbose']
1861     parser.add_option('-v', '--verbose', default=0, action='count',
1862                       help="print status messages, or debug with -vv")
1863     parser.add_option('-q', '--quiet', default=0, action='count',
1864                       help="report only file names, or nothing with -qq")
1865     parser.add_option('-r', '--repeat', default=True, action='store_true',
1866                       help="(obsolete) show all occurrences of the same error")
1867     parser.add_option('--first', action='store_false', dest='repeat',
1868                       help="show first occurrence of each error")
1869     parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE,
1870                       help="exclude files or directories which match these "
1871                            "comma separated patterns (default: %default)")
1872     parser.add_option('--filename', metavar='patterns', default='*.py',
1873                       help="when parsing directories, only check filenames "
1874                            "matching these comma separated patterns "
1875                            "(default: %default)")
1876     parser.add_option('--select', metavar='errors', default='',
1877                       help="select errors and warnings (e.g. E,W6)")
1878     parser.add_option('--ignore', metavar='errors', default='',
1879                       help="skip errors and warnings (e.g. E4,W) "
1880                            "(default: %s)" % DEFAULT_IGNORE)
1881     parser.add_option('--show-source', action='store_true',
1882                       help="show source code for each error")
1883     parser.add_option('--show-pep8', action='store_true',
1884                       help="show text of PEP 8 for each error "
1885                            "(implies --first)")
1886     parser.add_option('--statistics', action='store_true',
1887                       help="count errors and warnings")
1888     parser.add_option('--count', action='store_true',
1889                       help="print total number of errors and warnings "
1890                            "to standard error and set exit code to 1 if "
1891                            "total is not null")
1892     parser.add_option('--max-line-length', type='int', metavar='n',
1893                       default=MAX_LINE_LENGTH,
1894                       help="set maximum allowed line length "
1895                            "(default: %default)")
1896     parser.add_option('--hang-closing', action='store_true',
1897                       help="hang closing bracket instead of matching "
1898                            "indentation of opening bracket's line")
1899     parser.add_option('--format', metavar='format', default='default',
1900                       help="set the error format [default|pylint|<custom>]")
1901     parser.add_option('--diff', action='store_true',
1902                       help="report only lines changed according to the "
1903                            "unified diff received on STDIN")
1904     group = parser.add_option_group("Testing Options")
1905     if os.path.exists(TESTSUITE_PATH):
1906         group.add_option('--testsuite', metavar='dir',
1907                          help="run regression tests from dir")
1908         group.add_option('--doctest', action='store_true',
1909                          help="run doctest on myself")
1910     group.add_option('--benchmark', action='store_true',
1911                      help="measure processing speed")
1912     return parser
1913
1914
1915 def read_config(options, args, arglist, parser):
1916     """Read both user configuration and local configuration."""
1917     config = RawConfigParser()
1918
1919     user_conf = options.config
1920     if user_conf and os.path.isfile(user_conf):
1921         if options.verbose:
1922             print('user configuration: %s' % user_conf)
1923         config.read(user_conf)
1924
1925     local_dir = os.curdir
1926     parent = tail = args and os.path.abspath(os.path.commonprefix(args))
1927     while tail:
1928         if config.read([os.path.join(parent, fn) for fn in PROJECT_CONFIG]):
1929             local_dir = parent
1930             if options.verbose:
1931                 print('local configuration: in %s' % parent)
1932             break
1933         (parent, tail) = os.path.split(parent)
1934
1935     pep8_section = parser.prog
1936     if config.has_section(pep8_section):
1937         option_list = dict([(o.dest, o.type or o.action)
1938                             for o in parser.option_list])
1939
1940         # First, read the default values
1941         (new_options, __) = parser.parse_args([])
1942
1943         # Second, parse the configuration
1944         for opt in config.options(pep8_section):
1945             if opt.replace('_', '-') not in parser.config_options:
1946                 print("  unknown option '%s' ignored" % opt)
1947                 continue
1948             if options.verbose > 1:
1949                 print("  %s = %s" % (opt, config.get(pep8_section, opt)))
1950             normalized_opt = opt.replace('-', '_')
1951             opt_type = option_list[normalized_opt]
1952             if opt_type in ('int', 'count'):
1953                 value = config.getint(pep8_section, opt)
1954             elif opt_type == 'string':
1955                 value = config.get(pep8_section, opt)
1956                 if normalized_opt == 'exclude':
1957                     value = normalize_paths(value, local_dir)
1958             else:
1959                 assert opt_type in ('store_true', 'store_false')
1960                 value = config.getboolean(pep8_section, opt)
1961             setattr(new_options, normalized_opt, value)
1962
1963         # Third, overwrite with the command-line options
1964         (options, __) = parser.parse_args(arglist, values=new_options)
1965     options.doctest = options.testsuite = False
1966     return options
1967
1968
1969 def process_options(arglist=None, parse_argv=False, config_file=None,
1970                     parser=None):
1971     """Process options passed either via arglist or via command line args."""
1972     if not parser:
1973         parser = get_parser()
1974     if not parser.has_option('--config'):
1975         if config_file is True:
1976             config_file = DEFAULT_CONFIG
1977         group = parser.add_option_group("Configuration", description=(
1978             "The project options are read from the [%s] section of the "
1979             "tox.ini file or the setup.cfg file located in any parent folder "
1980             "of the path(s) being processed.  Allowed options are: %s." %
1981             (parser.prog, ', '.join(parser.config_options))))
1982         group.add_option('--config', metavar='path', default=config_file,
1983                          help="user config file location (default: %default)")
1984     # Don't read the command line if the module is used as a library.
1985     if not arglist and not parse_argv:
1986         arglist = []
1987     # If parse_argv is True and arglist is None, arguments are
1988     # parsed from the command line (sys.argv)
1989     (options, args) = parser.parse_args(arglist)
1990     options.reporter = None
1991
1992     if options.ensure_value('testsuite', False):
1993         args.append(options.testsuite)
1994     elif not options.ensure_value('doctest', False):
1995         if parse_argv and not args:
1996             if options.diff or any(os.path.exists(name)
1997                                    for name in PROJECT_CONFIG):
1998                 args = ['.']
1999             else:
2000                 parser.error('input not specified')
2001         options = read_config(options, args, arglist, parser)
2002         options.reporter = parse_argv and options.quiet == 1 and FileReport
2003
2004     options.filename = options.filename and options.filename.split(',')
2005     options.exclude = normalize_paths(options.exclude)
2006     options.select = options.select and options.select.split(',')
2007     options.ignore = options.ignore and options.ignore.split(',')
2008
2009     if options.diff:
2010         options.reporter = DiffReport
2011         stdin = stdin_get_value()
2012         options.selected_lines = parse_udiff(stdin, options.filename, args[0])
2013         args = sorted(options.selected_lines)
2014
2015     return options, args
2016
2017
2018 def _main():
2019     """Parse options and run checks on Python source."""
2020     import signal
2021
2022     # Handle "Broken pipe" gracefully
2023     try:
2024         signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1))
2025     except AttributeError:
2026         pass    # not supported on Windows
2027
2028     pep8style = StyleGuide(parse_argv=True, config_file=True)
2029     options = pep8style.options
2030     if options.doctest or options.testsuite:
2031         from testsuite.support import run_tests
2032         report = run_tests(pep8style)
2033     else:
2034         report = pep8style.check_files()
2035     if options.statistics:
2036         report.print_statistics()
2037     if options.benchmark:
2038         report.print_benchmark()
2039     if options.testsuite and not options.quiet:
2040         report.print_results()
2041     if report.total_errors:
2042         if options.count:
2043             sys.stderr.write(str(report.total_errors) + '\n')
2044         sys.exit(1)
2045
2046 if __name__ == '__main__':
2047     _main()