pep8.py
Go to the documentation of this file.
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.2'
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  USER_CONFIG = os.path.expanduser(r'~\.pep8')
72  else:
73  USER_CONFIG = os.path.join(
74  os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'),
75  'pep8'
76  )
77 except ImportError:
78  USER_CONFIG = None
79 
80 PROJECT_CONFIG = ('setup.cfg', 'tox.ini', '.pep8')
81 TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite')
82 MAX_LINE_LENGTH = 79
83 REPORT_FORMAT = {
84  'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s',
85  'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s',
86 }
87 
88 PyCF_ONLY_AST = 1024
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])
100 # ERRORTOKEN is triggered by backticks in Python 3
101 SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN])
102 BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines']
103 
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+))? @@.*$')
120 
121 # Work around Python < 2.6 behaviour, which does not generate NL after
122 # a comment which is on a line by itself.
123 COMMENT_WITH_NL = tokenize.generate_tokens(['#\n'].pop).send(None)[1] == '#\n'
124 
125 
126 ##############################################################################
127 # Plugins (check functions) for physical lines
128 ##############################################################################
129 
130 
131 def tabs_or_spaces(physical_line, indent_char):
132  r"""Never mix tabs and spaces.
133 
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!
140 
141  Okay: if a == 0:\n a = 1\n b = 1
142  E101: if a == 0:\n a = 1\n\tb = 1
143  """
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"
148 
149 
150 def tabs_obsolete(physical_line):
151  r"""For new projects, spaces-only are strongly recommended over tabs.
152 
153  Okay: if True:\n return
154  W191: if True:\n\treturn
155  """
156  indent = INDENT_REGEX.match(physical_line).group(1)
157  if '\t' in indent:
158  return indent.index('\t'), "W191 indentation contains tabs"
159 
160 
161 def trailing_whitespace(physical_line):
162  r"""Trailing whitespace is superfluous.
163 
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.
166 
167  Okay: spam(1)\n#
168  W291: spam(1) \n#
169  W293: class Foo(object):\n \n bang = 12
170  """
171  physical_line = physical_line.rstrip('\n') # chr(10), newline
172  physical_line = physical_line.rstrip('\r') # chr(13), carriage return
173  physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L
174  stripped = physical_line.rstrip(' \t\v')
175  if physical_line != stripped:
176  if stripped:
177  return len(stripped), "W291 trailing whitespace"
178  else:
179  return 0, "W293 blank line contains whitespace"
180 
181 
182 def trailing_blank_lines(physical_line, lines, line_number, total_lines):
183  r"""Trailing blank lines are superfluous.
184 
185  Okay: spam(1)
186  W391: spam(1)\n
187 
188  However the last line should end with a new line (warning W292).
189  """
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"
196 
197 
198 def maximum_line_length(physical_line, max_line_length, multiline):
199  r"""Limit all lines to a maximum of 79 characters.
200 
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.
207 
208  Reports error E501.
209  """
210  line = physical_line.rstrip()
211  length = len(line)
212  if length > max_line_length and not noqa(line):
213  # Special case for long URLs in multi-line docstrings or comments,
214  # but still report the error when the 72 first chars are whitespaces.
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:
219  return
220  if hasattr(line, 'decode'): # Python 2
221  # The line could contain multi-byte characters
222  try:
223  length = len(line.decode('utf-8'))
224  except UnicodeError:
225  pass
226  if length > max_line_length:
227  return (max_line_length, "E501 line too long "
228  "(%d > %d characters)" % (length, max_line_length))
229 
230 
231 ##############################################################################
232 # Plugins (check functions) for logical lines
233 ##############################################################################
234 
235 
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.
239 
240  Method definitions inside a class are separated by a single blank line.
241 
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).
245 
246  Use blank lines in functions, sparingly, to indicate logical sections.
247 
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
250 
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
256  """
257  if line_number < 3 and not previous_logical:
258  return # Don't expect blank lines before the first line
259  if previous_logical.startswith('@'):
260  if blank_lines:
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 ', '@')):
265  if indent_level:
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
271 
272 
273 def extraneous_whitespace(logical_line):
274  r"""Avoid extraneous whitespace.
275 
276  Avoid extraneous whitespace in these situations:
277  - Immediately inside parentheses, brackets or braces.
278  - Immediately before a comma, semicolon, or colon.
279 
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 })
287 
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
291  """
292  line = logical_line
293  for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line):
294  text = match.group()
295  char = text.strip()
296  found = match.start()
297  if text == char + ' ':
298  # assert char in '([{'
299  yield found + 1, "E201 whitespace after '%s'" % char
300  elif line[found - 1] != ',':
301  code = ('E202' if char in '}])' else 'E203') # if char in ',;:'
302  yield found, "%s whitespace before '%s'" % (code, char)
303 
304 
305 def whitespace_around_keywords(logical_line):
306  r"""Avoid extraneous whitespace around keywords.
307 
308  Okay: True and False
309  E271: True and False
310  E272: True and False
311  E273: True and\tFalse
312  E274: True\tand False
313  """
314  for match in KEYWORD_REGEX.finditer(logical_line):
315  before, after = match.groups()
316 
317  if '\t' in before:
318  yield match.start(1), "E274 tab before keyword"
319  elif len(before) > 1:
320  yield match.start(1), "E272 multiple spaces before keyword"
321 
322  if '\t' in after:
323  yield match.start(2), "E273 tab after keyword"
324  elif len(after) > 1:
325  yield match.start(2), "E271 multiple spaces after keyword"
326 
327 
328 def missing_whitespace(logical_line):
329  r"""Each comma, semicolon or colon should be followed by whitespace.
330 
331  Okay: [a, b]
332  Okay: (3,)
333  Okay: a[1:4]
334  Okay: a[:4]
335  Okay: a[1:]
336  Okay: a[1:4:2]
337  E231: ['a','b']
338  E231: foo(bar,baz)
339  E231: [{'a':'b'}]
340  """
341  line = logical_line
342  for index in range(len(line) - 1):
343  char = line[index]
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('['):
348  continue # Slice syntax, no space required
349  if char == ',' and line[index + 1] == ')':
350  continue # Allow tuple with only one element: (3,)
351  yield index, "E231 missing whitespace after '%s'" % char
352 
353 
354 def indentation(logical_line, previous_logical, indent_char,
355  indent_level, previous_indent_level):
356  r"""Use 4 spaces per indentation level.
357 
358  For really old code that you don't want to mess up, you can continue to
359  use 8-space tabs.
360 
361  Okay: a = 1
362  Okay: if a == 0:\n a = 1
363  E111: a = 1
364  E114: # a = 1
365 
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
369 
370  Okay: a = 1\nb = 2
371  E113: a = 1\n b = 2
372  E116: a = 1\n # b = 2
373  """
374  c = 0 if logical_line else 3
375  tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)"
376  if indent_level % 4:
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")
383 
384 
385 def continued_indentation(logical_line, tokens, indent_level, hang_closing,
386  indent_char, noqa, verbose):
387  r"""Continuation lines indentation.
388 
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.
392 
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
396  continuation line.
397 
398  Okay: a = (\n)
399  E123: a = (\n )
400 
401  Okay: a = (\n 42)
402  E121: a = (\n 42)
403  E122: a = (\n42)
404  E123: a = (\n 42\n )
405  E124: a = (24,\n 42\n)
406  E125: if (\n b):\n pass
407  E126: a = (\n 42)
408  E127: a = (24,\n 42)
409  E128: a = (24,\n 42)
410  E129: if (a or\n b):\n pass
411  E131: a = (\n 42\n 24)
412  """
413  first_row = tokens[0][2][0]
414  nrows = 1 + tokens[-1][2][0] - first_row
415  if noqa or nrows == 1:
416  return
417 
418  # indent_next tells us whether the next block is indented; assuming
419  # that it is indented by 4 spaces, then we should not allow 4-space
420  # indents on the final continuation line; in turn, some other
421  # indents are allowed to have an extra 4 spaces.
422  indent_next = logical_line.endswith(':')
423 
424  row = depth = 0
425  valid_hangs = (4,) if indent_char != '\t' else (4, 8)
426  # remember how many brackets were opened on each line
427  parens = [0] * nrows
428  # relative indents of physical lines
429  rel_indent = [0] * nrows
430  # for each depth, collect a list of opening rows
431  open_rows = [[0]]
432  # for each depth, memorize the hanging indentation
433  hangs = [None]
434  # visual indents
435  indent_chances = {}
436  last_indent = tokens[0][2]
437  visual_indent = None
438  last_token_multiline = False
439  # for each depth, memorize the visual indent column
440  indent = [last_indent[1]]
441  if verbose >= 3:
442  print(">>> " + tokens[0][4].rstrip())
443 
444  for token_type, text, start, end, line in tokens:
445 
446  newline = row < start[0] - first_row
447  if newline:
448  row = start[0] - first_row
449  newline = not last_token_multiline and token_type not in NEWLINE
450 
451  if newline:
452  # this is the beginning of a continuation line.
453  last_indent = start
454  if verbose >= 3:
455  print("... " + line.rstrip())
456 
457  # record the initial indent.
458  rel_indent[row] = expand_indent(line) - indent_level
459 
460  # identify closing bracket
461  close_bracket = (token_type == tokenize.OP and text in ']})')
462 
463  # is the indent relative to an opening bracket line?
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
467  if hanging_indent:
468  break
469  if hangs[depth]:
470  hanging_indent = (hang == hangs[depth])
471  # is there any chance of visual indent?
472  visual_indent = (not close_bracket and hang > 0 and
473  indent_chances.get(start[1]))
474 
475  if close_bracket and indent[depth]:
476  # closing bracket for visual indent
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:
481  # closing bracket matches indentation of opening bracket's line
482  if hang_closing:
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:
486  # visual indent is broken
487  yield (start, "E128 continuation line "
488  "under-indented for visual indent")
489  elif hanging_indent or (indent_next and rel_indent[row] == 8):
490  # hanging indent is verified
491  if close_bracket and not hang_closing:
492  yield (start, "E123 closing bracket does not match "
493  "indentation of opening bracket's line")
494  hangs[depth] = hang
495  elif visual_indent is True:
496  # visual indent is verified
497  indent[depth] = start[1]
498  elif visual_indent in (text, str):
499  # ignore token lined up with matching one from a previous line
500  pass
501  else:
502  # indent is broken
503  if hang <= 0:
504  error = "E122", "missing indentation or outdented"
505  elif indent[depth]:
506  error = "E127", "over-indented for visual indent"
507  elif not close_bracket and hangs[depth]:
508  error = "E131", "unaligned for hanging indent"
509  else:
510  hangs[depth] = hang
511  if hang > 4:
512  error = "E126", "over-indented for hanging indent"
513  else:
514  error = "E121", "under-indented for hanging indent"
515  yield start, "%s continuation line %s" % error
516 
517  # look for visual indenting
518  if (parens[row] and
519  token_type not in (tokenize.NL, tokenize.COMMENT) and
520  not indent[depth]):
521  indent[depth] = start[1]
522  indent_chances[start[1]] = True
523  if verbose >= 4:
524  print("bracket depth %s indent to %s" % (depth, start[1]))
525  # deal with implicit string concatenation
526  elif (token_type in (tokenize.STRING, tokenize.COMMENT) or
527  text in ('u', 'ur', 'b', 'br')):
528  indent_chances[start[1]] = str
529  # special case for the "if" statement because len("if (") == 4
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)
534 
535  # keep track of bracket depth
536  if token_type == tokenize.OP:
537  if text in '([{':
538  depth += 1
539  indent.append(0)
540  hangs.append(None)
541  if len(open_rows) == depth:
542  open_rows.append([])
543  open_rows[depth].append(row)
544  parens[row] += 1
545  if verbose >= 4:
546  print("bracket depth %s seen, col %s, visual min = %s" %
547  (depth, start[1], indent[depth]))
548  elif text in ')]}' and depth > 0:
549  # parent indents should not be more than this one
550  prev_indent = indent.pop() or last_indent[1]
551  hangs.pop()
552  for d in range(depth):
553  if indent[d] > prev_indent:
554  indent[d] = 0
555  for ind in list(indent_chances):
556  if ind >= prev_indent:
557  del indent_chances[ind]
558  del open_rows[depth + 1:]
559  depth -= 1
560  if depth:
561  indent_chances[indent[depth]] = True
562  for idx in range(row, -1, -1):
563  if parens[idx]:
564  parens[idx] -= 1
565  break
566  assert len(indent) == depth + 1
567  if start[1] not in indent_chances:
568  # allow to line up tokens
569  indent_chances[start[1]] = text
570 
571  last_token_multiline = (start[0] != end[0])
572  if last_token_multiline:
573  rel_indent[end[0] - first_row] = rel_indent[row]
574 
575  if indent_next and expand_indent(line) == indent_level + 4:
576  pos = (start[0], indent[0] + 4)
577  if visual_indent:
578  code = "E129 visually indented line"
579  else:
580  code = "E125 continuation line"
581  yield pos, "%s with same indent as next logical line" % code
582 
583 
584 def whitespace_before_parameters(logical_line, tokens):
585  r"""Avoid extraneous whitespace.
586 
587  Avoid extraneous whitespace in the following situations:
588  - before the open parenthesis that starts the argument list of a
589  function call.
590  - before the open parenthesis that starts an indexing or slicing.
591 
592  Okay: spam(1)
593  E211: spam (1)
594 
595  Okay: dict['key'] = list[index]
596  E211: dict ['key'] = list[index]
597  E211: dict['key'] = list [index]
598  """
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
603  text in '([' and
604  start != prev_end and
605  (prev_type == tokenize.NAME or prev_text in '}])') and
606  # Syntax "class A (B):" is allowed, but avoid it
607  (index < 2 or tokens[index - 2][1] != 'class') and
608  # Allow "return (a.foo for a in range(5))"
609  not keyword.iskeyword(prev_text)):
610  yield prev_end, "E211 whitespace before '%s'" % text
611  prev_type = token_type
612  prev_text = text
613  prev_end = end
614 
615 
616 def whitespace_around_operator(logical_line):
617  r"""Avoid extraneous whitespace around an operator.
618 
619  Okay: a = 12 + 3
620  E221: a = 4 + 5
621  E222: a = 4 + 5
622  E223: a = 4\t+ 5
623  E224: a = 4 +\t5
624  """
625  for match in OPERATOR_REGEX.finditer(logical_line):
626  before, after = match.groups()
627 
628  if '\t' in before:
629  yield match.start(1), "E223 tab before operator"
630  elif len(before) > 1:
631  yield match.start(1), "E221 multiple spaces before operator"
632 
633  if '\t' in after:
634  yield match.start(2), "E224 tab after operator"
635  elif len(after) > 1:
636  yield match.start(2), "E222 multiple spaces after operator"
637 
638 
639 def missing_whitespace_around_operator(logical_line, tokens):
640  r"""Surround operators with a single space on either side.
641 
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).
646 
647  - If operators with different priorities are used, consider adding
648  whitespace around the operators with the lowest priorities.
649 
650  Okay: i = i + 1
651  Okay: submitted += 1
652  Okay: x = x * 2 - 1
653  Okay: hypot2 = x * x + y * y
654  Okay: c = (a + b) * (a - b)
655  Okay: foo(bar, key='word', *args, **kwargs)
656  Okay: alpha[:-i]
657 
658  E225: i=i+1
659  E225: submitted +=1
660  E225: x = x /2 - 1
661  E225: z = x **y
662  E226: c = (a+b) * (a-b)
663  E226: hypot2 = x*x + y*y
664  E227: c = a|b
665  E228: msg = fmt%(errno, errmsg)
666  """
667  parens = 0
668  need_space = False
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:
673  continue
674  if text in ('(', 'lambda'):
675  parens += 1
676  elif text == ')':
677  parens -= 1
678  if need_space:
679  if start != prev_end:
680  # Found a (probably) needed space
681  if need_space is not True and not need_space[1]:
682  yield (need_space[0],
683  "E225 missing whitespace around operator")
684  need_space = False
685  elif text == '>' and prev_text in ('<', '-'):
686  # Tolerate the "<>" operator, even if running Python 3
687  # Deal with Python 3's annotated return value "->"
688  pass
689  else:
690  if need_space is True or need_space[1]:
691  # A needed trailing space was not found
692  yield prev_end, "E225 missing whitespace around operator"
693  elif prev_text != '**':
694  code, optype = 'E226', 'arithmetic'
695  if prev_text == '%':
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))
701  need_space = False
702  elif token_type == tokenize.OP and prev_end is not None:
703  if text == '=' and parens:
704  # Allow keyword args or defaults: foo(bar=None).
705  pass
706  elif text in WS_NEEDED_OPERATORS:
707  need_space = True
708  elif text in UNARY_OPERATORS:
709  # Check if the operator is being used as a binary operator
710  # Allow unary operators: -123, -x, +1.
711  # Allow argument unpacking: foo(*args, **kwargs).
712  if (prev_text in '}])' if prev_type == tokenize.OP
713  else prev_text not in KEYWORDS):
714  need_space = None
715  elif text in WS_OPTIONAL_OPERATORS:
716  need_space = None
717 
718  if need_space is None:
719  # Surrounding space is optional, but ensure that
720  # trailing space matches opening space
721  need_space = (prev_end, start != prev_end)
722  elif need_space and start == prev_end:
723  # A needed opening space was not found
724  yield prev_end, "E225 missing whitespace around operator"
725  need_space = False
726  prev_type = token_type
727  prev_text = text
728  prev_end = end
729 
730 
731 def whitespace_around_comma(logical_line):
732  r"""Avoid extraneous whitespace after a comma or a colon.
733 
734  Note: these checks are disabled by default
735 
736  Okay: a = (1, 2)
737  E241: a = (1, 2)
738  E242: a = (1,\t2)
739  """
740  line = logical_line
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]
745  else:
746  yield found, "E241 multiple spaces after '%s'" % m.group()[0]
747 
748 
750  r"""Don't use spaces around the '=' sign in function arguments.
751 
752  Don't use spaces around the '=' sign when used to indicate a
753  keyword argument or a default parameter value.
754 
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):
762 
763  E251: def complex(real, imag = 0.0):
764  E251: return magic(r = real, i = imag)
765  """
766  parens = 0
767  no_space = False
768  prev_end = None
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:
774  continue
775  if no_space:
776  no_space = False
777  if start != prev_end:
778  yield (prev_end, message)
779  if token_type == tokenize.OP:
780  if text == '(':
781  parens += 1
782  elif text == ')':
783  parens -= 1
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:
789  no_space = True
790  if start != prev_end:
791  yield (prev_end, message)
792  if not parens:
793  annotated_func_arg = False
794 
795  prev_end = end
796 
797 
798 def whitespace_before_comment(logical_line, tokens):
799  r"""Separate inline comments by at least two spaces.
800 
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.
804 
805  Each line of a block comment starts with a # and a single space
806  (unless it is indented text inside the comment).
807 
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
814  E265: #Block comment
815  E266: ### Block comment
816  """
817  prev_end = (0, 0)
818  for token_type, text, start, end, line in tokens:
819  if token_type == tokenize.COMMENT:
820  inline_comment = line[:start[1]].strip()
821  if inline_comment:
822  if prev_end[0] == start[0] and start[1] < prev_end[1] + 2:
823  yield (prev_end,
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 '#')
827  if inline_comment:
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 '# '"
833  elif comment:
834  yield start, "E266 too many leading '#' for block comment"
835  elif token_type != tokenize.NL:
836  prev_end = end
837 
838 
839 def imports_on_separate_lines(logical_line):
840  r"""Imports should usually be on separate lines.
841 
842  Okay: import os\nimport sys
843  E401: import sys, os
844 
845  Okay: from subprocess import Popen, PIPE
846  Okay: from myclas import MyClass
847  Okay: from foo.bar.yourclass import YourClass
848  Okay: import myclass
849  Okay: import foo.bar.yourclass
850  """
851  line = logical_line
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"
856 
857 
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.
862 
863  Okay: import os
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
869  E402: a=1\nimport os
870  E402: 'One string'\n"Two string"\nimport os
871  E402: a=1\nfrom sys import x
872 
873  Okay: if x:\n import os
874  """
875  def is_string_literal(line):
876  if line[0] in 'uUbB':
877  line = line[1:]
878  if line and line[0] in 'rR':
879  line = line[1:]
880  return line and (line[0] == '"' or line[0] == "'")
881 
882  allowed_try_keywords = ('try', 'except', 'else', 'finally')
883 
884  if indent_level: # Allow imports in conditional statements or functions
885  return
886  if not logical_line: # Allow empty lines or comments
887  return
888  if noqa:
889  return
890  line = logical_line
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):
895  # Allow try, except, else, finally keywords intermixed with imports in
896  # order to support conditional importing
897  return
898  elif is_string_literal(line):
899  # The first literal is a docstring, allow it. Otherwise, report error.
900  if checker_state.get('seen_docstring', False):
901  checker_state['seen_non_imports'] = True
902  else:
903  checker_state['seen_docstring'] = True
904  else:
905  checker_state['seen_non_imports'] = True
906 
907 
908 def compound_statements(logical_line):
909  r"""Compound statements (on the same line) are generally discouraged.
910 
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!
914 
915  Always use a def statement instead of an assignment statement that
916  binds a lambda expression directly to a name.
917 
918  Okay: if foo == 'blah':\n do_blah_thing()
919  Okay: do_one()
920  Okay: do_two()
921  Okay: do_three()
922 
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
935  """
936  line = logical_line
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 # {'a': 1} (dict)
942  before.count('[') <= before.count(']') and # [1:2] (slice)
943  before.count('(') <= before.count(')'))): # (annotation)
944  lambda_kw = LAMBDA_REGEX.search(before)
945  if lambda_kw:
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 "
949  "def")
950  break
951  if before.startswith('def '):
952  yield 0, "E704 multiple statements on one line (def)"
953  else:
954  yield found, "E701 multiple statements on one line (colon)"
955  found = line.find(':', found + 1)
956  found = line.find(';')
957  while -1 < found:
958  if found < last_char:
959  yield found, "E702 multiple statements on one line (semicolon)"
960  else:
961  yield found, "E703 statement ends with a semicolon"
962  found = line.find(';', found + 1)
963 
964 
965 def explicit_line_join(logical_line, tokens):
966  r"""Avoid explicit line join between brackets.
967 
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.
972 
973  E502: aaa = [123, \\n 123]
974  E502: aaa = ("bbb " \\n "ccc")
975 
976  Okay: aaa = [123,\n 123]
977  Okay: aaa = ("bbb "\n "ccc")
978  Okay: aaa = "bbb " \\n "ccc"
979  Okay: aaa = 123 # \\
980  """
981  prev_start = prev_end = parens = 0
982  comment = False
983  backslash = None
984  for token_type, text, start, end, line in tokens:
985  if token_type == tokenize.COMMENT:
986  comment = True
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)
992  else:
993  backslash = None
994  prev_start = prev_end = end[0]
995  else:
996  prev_start = start[0]
997  if token_type == tokenize.OP:
998  if text in '([{':
999  parens += 1
1000  elif text in ')]}':
1001  parens -= 1
1002 
1003 
1004 def break_around_binary_operator(logical_line, tokens):
1005  r"""
1006  Avoid breaks before binary operators.
1007 
1008  The preferred place to break around a binary operator is after the
1009  operator, not before it.
1010 
1011  W503: (width == 0\n + height == 0)
1012  W503: (width == 0\n and height == 0)
1013 
1014  Okay: (width == 0 +\n height == 0)
1015  Okay: foo(\n -x)
1016  Okay: foo(x\n [])
1017  Okay: x = '''\n''' + ''
1018  Okay: foo(x,\n -y)
1019  Okay: foo(x, # comment\n -y)
1020  """
1021  def is_binary_operator(token_type, text):
1022  # The % character is strictly speaking a binary operator, but the
1023  # common usage seems to be to put it next to the format parameters,
1024  # after a line break.
1025  return ((token_type == tokenize.OP or text in ['and', 'or']) and
1026  text not in "()[]{},:.;@=%")
1027 
1028  line_break = False
1029  unary_context = True
1030  for token_type, text, start, end, line in tokens:
1031  if token_type == tokenize.COMMENT:
1032  continue
1033  if ('\n' in text or '\r' in text) and token_type != tokenize.STRING:
1034  line_break = True
1035  else:
1036  if (is_binary_operator(token_type, text) and line_break and
1037  not unary_context):
1038  yield start, "W503 line break before binary operator"
1039  unary_context = text in '([{,;'
1040  line_break = False
1041 
1042 
1043 def comparison_to_singleton(logical_line, noqa):
1044  r"""Comparison to singletons should use "is" or "is not".
1045 
1046  Comparisons to singletons like None should always be done
1047  with "is" or "is not", never the equality operators.
1048 
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:
1054 
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!
1059  """
1060  match = not noqa and COMPARE_SINGLETON_REGEX.search(logical_line)
1061  if match:
1062  singleton = match.group(1) or match.group(3)
1063  same = (match.group(2) == '==')
1064 
1065  msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton)
1066  if singleton in ('None',):
1067  code = 'E711'
1068  else:
1069  code = 'E712'
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))
1075 
1076 
1077 def comparison_negative(logical_line):
1078  r"""Negative comparison should be done using "not in" and "is not".
1079 
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
1088  """
1089  match = COMPARE_NEGATIVE_REGEX.search(logical_line)
1090  if match:
1091  pos = match.start(1)
1092  if match.group(2) == 'in':
1093  yield pos, "E713 test for membership should be 'not in'"
1094  else:
1095  yield pos, "E714 test for object identity should be 'is not'"
1096 
1097 
1098 def comparison_type(logical_line, noqa):
1099  r"""Object type comparisons should always use isinstance().
1100 
1101  Do not compare types directly.
1102 
1103  Okay: if isinstance(obj, int):
1104  E721: if type(obj) is type(1):
1105 
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:
1109 
1110  Okay: if isinstance(obj, basestring):
1111  Okay: if type(a1) is type(b1):
1112  """
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:
1117  return # Allow comparison for types which are not obvious
1118  yield match.start(), "E721 do not compare types, use 'isinstance()'"
1119 
1120 
1121 def python_3000_has_key(logical_line, noqa):
1122  r"""The {}.has_key() method is removed in Python 3: use the 'in' operator.
1123 
1124  Okay: if "alph" in d:\n print d["alph"]
1125  W601: assert d.has_key('alph')
1126  """
1127  pos = logical_line.find('.has_key(')
1128  if pos > -1 and not noqa:
1129  yield pos, "W601 .has_key() is deprecated, use 'in'"
1130 
1131 
1132 def python_3000_raise_comma(logical_line):
1133  r"""When raising an exception, use "raise ValueError('message')".
1134 
1135  The older form is removed in Python 3.
1136 
1137  Okay: raise DummyError("Message")
1138  W602: raise DummyError, "Message"
1139  """
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"
1143 
1144 
1145 def python_3000_not_equal(logical_line):
1146  r"""New code should always use != instead of <>.
1147 
1148  The older syntax is removed in Python 3.
1149 
1150  Okay: if a != 'no':
1151  W603: if a <> 'no':
1152  """
1153  pos = logical_line.find('<>')
1154  if pos > -1:
1155  yield pos, "W603 '<>' is deprecated, use '!='"
1156 
1157 
1158 def python_3000_backticks(logical_line):
1159  r"""Backticks are removed in Python 3: use repr() instead.
1160 
1161  Okay: val = repr(1 + 2)
1162  W604: val = `1 + 2`
1163  """
1164  pos = logical_line.find('`')
1165  if pos > -1:
1166  yield pos, "W604 backticks are deprecated, use 'repr()'"
1167 
1168 
1169 ##############################################################################
1170 # Helper functions
1171 ##############################################################################
1172 
1173 
1174 if '' == ''.encode():
1175  # Python 2: implicit encoding.
1176  def readlines(filename):
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
1182 else:
1183  # Python 3
1184  def readlines(filename):
1185  """Read the source code."""
1186  try:
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):
1192  # Fall back if file encoding is improperly declared
1193  with open(filename, encoding='latin-1') as f:
1194  return f.readlines()
1195  isidentifier = str.isidentifier
1196 
1198  return TextIOWrapper(sys.stdin.buffer, errors='ignore').read()
1199 noqa = re.compile(r'# no(?:qa|pep8)\b', re.I).search
1200 
1201 
1202 def expand_indent(line):
1203  r"""Return the amount of indentation.
1204 
1205  Tabs are expanded to the next multiple of 8.
1206 
1207  >>> expand_indent(' ')
1208  4
1209  >>> expand_indent('\t')
1210  8
1211  >>> expand_indent(' \t')
1212  8
1213  >>> expand_indent(' \t')
1214  16
1215  """
1216  if '\t' not in line:
1217  return len(line) - len(line.lstrip())
1218  result = 0
1219  for char in line:
1220  if char == '\t':
1221  result = result // 8 * 8 + 8
1222  elif char == ' ':
1223  result += 1
1224  else:
1225  break
1226  return result
1227 
1228 
1229 def mute_string(text):
1230  """Replace contents with 'xxx' to prevent syntax matching.
1231 
1232  >>> mute_string('"abc"')
1233  '"xxx"'
1234  >>> mute_string("'''abc'''")
1235  "'''xxx'''"
1236  >>> mute_string("r'abc'")
1237  "r'xxx'"
1238  """
1239  # String modifiers (e.g. u or r)
1240  start = text.index(text[-1]) + 1
1241  end = len(text) - 1
1242  # Triple quotes
1243  if text[-3:] in ('"""', "'''"):
1244  start += 2
1245  end -= 2
1246  return text[:start] + 'x' * (end - start) + text[end:]
1247 
1248 
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.
1253  rv = {}
1254  path = nrows = None
1255  for line in diff.splitlines():
1256  if nrows:
1257  if line[:1] != '-':
1258  nrows -= 1
1259  continue
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/':
1267  path = path[2:]
1268  rv[path] = set()
1269  return dict([(os.path.join(parent, path), rows)
1270  for (path, rows) in rv.items()
1271  if rows and filename_match(path, patterns)])
1272 
1273 
1274 def normalize_paths(value, parent=os.curdir):
1275  """Parse a comma-separated list of paths.
1276 
1277  Return a list of absolute paths.
1278  """
1279  if not value:
1280  return []
1281  if isinstance(value, list):
1282  return value
1283  paths = []
1284  for path in value.split(','):
1285  path = path.strip()
1286  if '/' in path:
1287  path = os.path.abspath(os.path.join(parent, path))
1288  paths.append(path.rstrip('/'))
1289  return paths
1290 
1291 
1292 def filename_match(filename, patterns, default=True):
1293  """Check if patterns contains a pattern that matches filename.
1294 
1295  If patterns is unspecified, this always returns True.
1296  """
1297  if not patterns:
1298  return default
1299  return any(fnmatch(filename, pattern) for pattern in patterns)
1300 
1301 
1302 def _is_eol_token(token):
1303  return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n'
1304 if COMMENT_WITH_NL:
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])
1308 
1309 ##############################################################################
1310 # Framework to run all checks
1311 ##############################################################################
1312 
1313 
1314 _checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}}
1315 
1316 
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 [])
1322  else:
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'):
1327  if codes is None:
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)
1333 
1334 
1335 def init_checks_registry():
1336  """Register all globally visible functions.
1337 
1338  The first argument name is either 'physical_line' or 'logical_line'.
1339  """
1340  mod = inspect.getmodule(register_check)
1341  for (name, function) in inspect.getmembers(mod, inspect.isfunction):
1342  register_check(function)
1343 init_checks_registry()
1344 
1345 
1346 class Checker(object):
1347  """Load a Python source file, tokenize it, check coding style."""
1348 
1349  def __init__(self, filename=None, lines=None,
1350  options=None, report=None, **kwargs):
1351  if options is None:
1352  options = StyleGuide(kwargs).options
1353  else:
1354  assert not kwargs
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)
1372  elif lines is None:
1373  try:
1374  self.lines = readlines(filename)
1375  except IOError:
1376  (exc_type, exc) = sys.exc_info()[:2]
1377  self._io_error = '%s: %s' % (exc_type.__name__, exc)
1378  self.lines = []
1379  else:
1380  self.lines = lines
1381  if self.lines:
1382  ord0 = ord(self.lines[0][0])
1383  if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM
1384  if ord0 == 0xfeff:
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
1390 
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]
1396  if len(offset) > 2:
1397  offset = offset[1:3]
1398  else:
1399  offset = (1, 0)
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)
1403 
1404  def readline(self):
1405  """Get the next line from the input buffer."""
1406  if self.line_number >= self.total_lines:
1407  return ''
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]
1412  return line
1413 
1414  def run_check(self, check, argument_names):
1415  """Run a check plugin."""
1416  arguments = []
1417  for name in argument_names:
1418  arguments.append(getattr(self, name))
1419  return check(*arguments)
1420 
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, {})
1425 
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]
1437 
1438  def build_tokens_line(self):
1439  """Build a logical line from tokens."""
1440  logical = []
1441  comments = []
1442  length = 0
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:
1446  continue
1447  if not mapping:
1448  mapping = [(0, start)]
1449  if token_type == tokenize.COMMENT:
1450  comments.append(text)
1451  continue
1452  if token_type == tokenize.STRING:
1453  text = mute_string(text)
1454  if prev_row:
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
1459  text not in '}])'):
1460  text = ' ' + text
1461  elif prev_col != start_col: # different column
1462  text = line[prev_col:start_col] + text
1463  logical.append(text)
1464  length += len(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))
1469  return mapping
1470 
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()
1475 
1476  if not mapping:
1477  return
1478 
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:
1488  print(' ' + name)
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:
1494  break
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
1501  self.tokens = []
1502 
1503  def check_ast(self):
1504  """Build the file's AST and run all AST checks."""
1505  try:
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)
1514 
1515  def generate_tokens(self):
1516  """Tokenize the file, run physical line checks and yield tokens."""
1517  if self._io_error:
1518  self.report_error(1, 0, 'E902 %s' % self._io_error, readlines)
1519  tokengen = tokenize.generate_tokens(self.readline)
1520  try:
1521  for token in tokengen:
1522  if token[2][0] > self.total_lines:
1523  return
1524  self.maybe_check_physical(token)
1525  yield token
1526  except (SyntaxError, tokenize.TokenError):
1527  self.report_invalid_syntax()
1528 
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.
1542  #
1543  # Subtleties:
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
1550  if noqa(token[4]):
1551  return
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
1558 
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:
1564  self.check_ast()
1565  self.line_number = 0
1566  self.indent_char = None
1567  self.indent_level = self.previous_indent_level = 0
1568  self.previous_logical = ''
1569  self.tokens = []
1570  self.blank_lines = self.blank_before = 0
1571  parens = 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])
1578  else:
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:
1583  if text in '([{':
1584  parens += 1
1585  elif text in '}])':
1586  parens -= 1
1587  elif not parens:
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
1595  del self.tokens[0]
1596  else:
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
1601  token = list(token)
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()
1606  if self.tokens:
1607  self.check_physical(self.lines[-1])
1608  self.check_logical()
1609  return self.report.get_file_results()
1610 
1611 
1612 class BaseReport(object):
1613  """Collect the results of the checks."""
1614 
1615  print_filename = False
1616 
1617  def __init__(self, options):
1618  self._benchmark_keys = options.benchmark_keys
1619  self._ignore_code = options.ignore_code
1620  # Results
1621  self.elapsed = 0
1622  self.total_errors = 0
1623  self.counters = dict.fromkeys(self._benchmark_keys, 0)
1624  self.messages = {}
1625 
1626  def start(self):
1627  """Start the timer."""
1628  self._start_time = time.time()
1629 
1630  def stop(self):
1631  """Stop the timer."""
1632  self.elapsed = time.time() - self._start_time
1633 
1634  def init_file(self, filename, lines, expected, line_offset):
1635  """Signal a new file."""
1636  self.filename = filename
1637  self.lines = lines
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)
1643 
1644  def increment_logical_line(self):
1645  """Signal a new logical line."""
1646  self.counters['logical lines'] += 1
1647 
1648  def error(self, line_number, offset, text, check):
1649  """Report an error, according to options."""
1650  code = text[:4]
1651  if self._ignore_code(code):
1652  return
1653  if code in self.counters:
1654  self.counters[code] += 1
1655  else:
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:
1660  return
1661  if self.print_filename and not self.file_errors:
1662  print(self.filename)
1663  self.file_errors += 1
1664  self.total_errors += 1
1665  return code
1666 
1667  def get_file_results(self):
1668  """Return the count of errors and warnings for this file."""
1669  return self.file_errors
1670 
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)])
1675 
1676  def get_statistics(self, prefix=''):
1677  """Get statistics for message codes that start with the prefix.
1678 
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
1683  """
1684  return ['%-7s %s %s' % (self.counters[key], key, self.messages[key])
1685  for key in sorted(self.messages) if key.startswith(prefix)]
1686 
1687  def print_statistics(self, prefix=''):
1688  """Print overall statistics (number of errors and warnings)."""
1689  for line in self.get_statistics(prefix):
1690  print(line)
1691 
1692  def print_benchmark(self):
1693  """Print benchmark numbers."""
1694  print('%-7.2f %s' % (self.elapsed, 'seconds elapsed'))
1695  if self.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]))
1700 
1701 
1702 class FileReport(BaseReport):
1703  """Collect the results of the checks and print only the filenames."""
1704  print_filename = True
1705 
1706 
1707 class StandardReport(BaseReport):
1708  """Collect and print the results of the checks."""
1709 
1710  def __init__(self, options):
1711  super(StandardReport, self).__init__(options)
1712  self._fmt = REPORT_FORMAT.get(options.format.lower(),
1713  options.format)
1714  self._repeat = options.repeat
1715  self._show_source = options.show_source
1716  self._show_pep8 = options.show_pep8
1717 
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)
1723 
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,
1727  text, check)
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__))
1731  return code
1732 
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:
1737  print(self._fmt % {
1738  'path': self.filename,
1739  'row': self.line_offset + line_number, 'col': offset + 1,
1740  'code': code, 'text': text,
1741  })
1742  if self._show_source:
1743  if line_number > len(self.lines):
1744  line = ''
1745  else:
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())
1751 
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
1757  # len(line) < 8192.
1758  sys.stdout.flush()
1759  return self.file_errors
1760 
1761 
1762 class DiffReport(StandardReport):
1763  """Collect and print the results for the changed lines only."""
1764 
1765  def __init__(self, options):
1766  super(DiffReport, self).__init__(options)
1767  self._selected = options.selected_lines
1768 
1769  def error(self, line_number, offset, text, check):
1770  if line_number not in self._selected[self.filename]:
1771  return
1772  return super(DiffReport, self).error(line_number, offset, text, check)
1773 
1774 
1775 class StyleGuide(object):
1776  """Initialize a PEP-8 instance with few options."""
1777 
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)
1789  if options_dict:
1790  options.__dict__.update(options_dict)
1791  if 'paths' in options_dict:
1792  self.paths = options_dict['paths']
1793 
1794  self.runner = self.input_file
1795  self.options = options
1796 
1797  if not options.reporter:
1798  options.reporter = BaseReport if options.quiet else StandardReport
1799 
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(','))
1805  else:
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')
1813  self.init_report()
1814 
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
1819 
1820  def check_files(self, paths=None):
1821  """Run all checks on the paths."""
1822  if paths is None:
1823  paths = self.paths
1824  report = self.options.report
1825  runner = self.runner
1826  report.start()
1827  try:
1828  for path in paths:
1829  if os.path.isdir(path):
1830  self.input_dir(path)
1831  elif not self.excluded(path):
1832  runner(path)
1833  except KeyboardInterrupt:
1834  print('... stopped')
1835  report.stop()
1836  return report
1837 
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)
1845 
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):
1850  return 0
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):
1856  if verbose:
1857  print('directory ' + root)
1858  counters['directories'] += 1
1859  for subdir in sorted(dirs):
1860  if self.excluded(subdir, root):
1861  dirs.remove(subdir)
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))
1867 
1868  def excluded(self, filename, parent=None):
1869  """Check if the file should be excluded.
1870 
1871  Check if 'options.exclude' contains a pattern that matches filename.
1872  """
1873  if not self.options.exclude:
1874  return False
1875  basename = os.path.basename(filename)
1876  if filename_match(basename, self.options.exclude):
1877  return True
1878  if parent:
1879  filename = os.path.join(parent, filename)
1880  filename = os.path.abspath(filename)
1881  return filename_match(filename, self.options.exclude)
1882 
1883  def ignore_code(self, code):
1884  """Check if the error code should be ignored.
1885 
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.
1889  """
1890  if len(code) < 4 and any(s.startswith(code)
1891  for s in self.options.select):
1892  return False
1893  return (code.startswith(self.options.ignore) and
1894  not code.startswith(self.options.select))
1895 
1896  def get_checks(self, argument_name):
1897  """Get all the checks for this category.
1898 
1899  Find all globally visible functions where the first argument name
1900  starts with argument_name and which contain selected tests.
1901  """
1902  checks = []
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)
1908 
1909 
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")
1968  return parser
1969 
1970 
1971 def read_config(options, args, arglist, parser):
1972  """Read and parse configurations
1973 
1974  If a config file is specified on the command line with the "--config"
1975  option, then only it is used for configuration.
1976 
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.
1980  """
1981  config = RawConfigParser()
1982 
1983  cli_conf = options.config
1984 
1985  local_dir = os.curdir
1986 
1987  if cli_conf and os.path.isfile(cli_conf):
1988  if options.verbose:
1989  print('cli configuration: %s' % cli_conf)
1990  config.read(cli_conf)
1991  else:
1992  if USER_CONFIG and os.path.isfile(USER_CONFIG):
1993  if options.verbose:
1994  print('user configuration: %s' % USER_CONFIG)
1995  config.read(USER_CONFIG)
1996 
1997  parent = tail = args and os.path.abspath(os.path.commonprefix(args))
1998  while tail:
1999  if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG):
2000  local_dir = parent
2001  if options.verbose:
2002  print('local configuration: in %s' % parent)
2003  break
2004  (parent, tail) = os.path.split(parent)
2005 
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])
2010 
2011  # First, read the default values
2012  (new_options, __) = parser.parse_args([])
2013 
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)
2018  continue
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)
2029  else:
2030  assert opt_type in ('store_true', 'store_false')
2031  value = config.getboolean(pep8_section, opt)
2032  setattr(new_options, normalized_opt, value)
2033 
2034  # Third, overwrite with the command-line options
2035  (options, __) = parser.parse_args(arglist, values=new_options)
2036  options.doctest = options.testsuite = False
2037  return options
2038 
2039 
2040 def process_options(arglist=None, parse_argv=False, config_file=None,
2041  parser=None):
2042  """Process options passed either via arglist or via command line args.
2043 
2044  Passing in the ``config_file`` parameter allows other tools, such as flake8
2045  to specify their own options to be processed in pep8.
2046  """
2047  if not parser:
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:
2059  arglist = []
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
2064 
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):
2071  args = ['.']
2072  else:
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
2076 
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(',')
2081 
2082  if options.diff:
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)
2087 
2088  return options, args
2089 
2090 
2091 def _main():
2092  """Parse options and run checks on Python source."""
2093  import signal
2094 
2095  # Handle "Broken pipe" gracefully
2096  try:
2097  signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1))
2098  except AttributeError:
2099  pass # not supported on Windows
2100 
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)
2106  else:
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:
2115  if options.count:
2116  sys.stderr.write(str(report.total_errors) + '\n')
2117  sys.exit(1)
2118 
2119 if __name__ == '__main__':
2120  _main()
def maximum_line_length(physical_line, max_line_length, multiline)
Definition: pep8.py:198
stdin_get_value
Definition: pep8.py:1181
def python_3000_backticks(logical_line)
Definition: pep8.py:1158
def module_imports_on_top_of_file(logical_line, indent_level, checker_state, noqa)
Definition: pep8.py:859
def comparison_type(logical_line, noqa)
Definition: pep8.py:1098
def whitespace_around_keywords(logical_line)
Definition: pep8.py:305
def mute_string(text)
Definition: pep8.py:1229
def missing_whitespace(logical_line)
Definition: pep8.py:328
def trailing_whitespace(physical_line)
Definition: pep8.py:161
def whitespace_around_named_parameter_equals(logical_line, tokens)
Definition: pep8.py:749
def tabs_obsolete(physical_line)
Definition: pep8.py:150
def continued_indentation(logical_line, tokens, indent_level, hang_closing, indent_char, noqa, verbose)
Definition: pep8.py:386
def indentation(logical_line, previous_logical, indent_char, indent_level, previous_indent_level)
Definition: pep8.py:355
def missing_whitespace_around_operator(logical_line, tokens)
Definition: pep8.py:639
def whitespace_before_parameters(logical_line, tokens)
Definition: pep8.py:584
def readlines(filename)
Helper functions.
Definition: pep8.py:1176
def comparison_to_singleton(logical_line, noqa)
Definition: pep8.py:1043
def trailing_blank_lines(physical_line, lines, line_number, total_lines)
Definition: pep8.py:182
def blank_lines(logical_line, blank_lines, indent_level, line_number, blank_before, previous_logical, previous_indent_level)
Plugins (check functions) for logical lines.
Definition: pep8.py:237
def expand_indent(line)
Definition: pep8.py:1202
def break_around_binary_operator(logical_line, tokens)
Definition: pep8.py:1004
def python_3000_has_key(logical_line, noqa)
Definition: pep8.py:1121
def whitespace_before_comment(logical_line, tokens)
Definition: pep8.py:798
def tabs_or_spaces(physical_line, indent_char)
Plugins (check functions) for physical lines.
Definition: pep8.py:131
def python_3000_not_equal(logical_line)
Definition: pep8.py:1145
def python_3000_raise_comma(logical_line)
Definition: pep8.py:1132
def explicit_line_join(logical_line, tokens)
Definition: pep8.py:965
def whitespace_around_comma(logical_line)
Definition: pep8.py:731
def whitespace_around_operator(logical_line)
Definition: pep8.py:616
def compound_statements(logical_line)
Definition: pep8.py:908
def extraneous_whitespace(logical_line)
Definition: pep8.py:273
def comparison_negative(logical_line)
Definition: pep8.py:1077
def imports_on_separate_lines(logical_line)
Definition: pep8.py:839


roslint
Author(s): Mike Purvis, Jack O'Quin
autogenerated on Wed May 1 2019 02:23:59