pycodestyle.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # pycodestyle.py - Check Python source code formatting, according to
3 # PEP 8
4 #
5 # Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net>
6 # Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com>
7 # Copyright (C) 2014-2016 Ian Lee <ianlee1521@gmail.com>
8 #
9 # Permission is hereby granted, free of charge, to any person
10 # obtaining a copy of this software and associated documentation files
11 # (the "Software"), to deal in the Software without restriction,
12 # including without limitation the rights to use, copy, modify, merge,
13 # publish, distribute, sublicense, and/or sell copies of the Software,
14 # and to permit persons to whom the Software is furnished to do so,
15 # subject to the following conditions:
16 #
17 # The above copyright notice and this permission notice shall be
18 # included in all copies or substantial portions of the Software.
19 #
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24 # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 # SOFTWARE.
28 
29 r"""
30 Check Python source code formatting, according to PEP 8.
31 
32 For usage and a list of options, try this:
33 $ python pycodestyle.py -h
34 
35 This program and its regression test suite live here:
36 https://github.com/pycqa/pycodestyle
37 
38 Groups of errors and warnings:
39 E errors
40 W warnings
41 100 indentation
42 200 whitespace
43 300 blank lines
44 400 imports
45 500 line length
46 600 deprecation
47 700 statements
48 900 syntax error
49 """
50 from __future__ import with_statement
51 
52 import inspect
53 import keyword
54 import os
55 import re
56 import sys
57 import time
58 import tokenize
59 import warnings
60 import bisect
61 
62 try:
63  from functools import lru_cache
64 except ImportError:
65  def lru_cache(maxsize=128): # noqa as it's a fake implementation.
66  """Does not really need a real a lru_cache, it's just
67  optimization, so let's just do nothing here. Python 3.2+ will
68  just get better performances, time to upgrade?
69  """
70  return lambda function: function
71 
72 from fnmatch import fnmatch
73 from optparse import OptionParser
74 
75 try:
76  from configparser import RawConfigParser
77  from io import TextIOWrapper
78 except ImportError:
79  from ConfigParser import RawConfigParser
80 
81 __version__ = '2.5.0'
82 
83 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox'
84 DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504'
85 try:
86  if sys.platform == 'win32':
87  USER_CONFIG = os.path.expanduser(r'~\.pycodestyle')
88  else:
89  USER_CONFIG = os.path.join(
90  os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'),
91  'pycodestyle'
92  )
93 except ImportError:
94  USER_CONFIG = None
95 
96 PROJECT_CONFIG = ('setup.cfg', 'tox.ini')
97 TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite')
98 MAX_LINE_LENGTH = 79
99 # Number of blank lines between various code parts.
100 BLANK_LINES_CONFIG = {
101  # Top level class and function.
102  'top_level': 2,
103  # Methods and nested class and function.
104  'method': 1,
105 }
106 MAX_DOC_LENGTH = 72
107 REPORT_FORMAT = {
108  'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s',
109  'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s',
110 }
111 
112 PyCF_ONLY_AST = 1024
113 SINGLETONS = frozenset(['False', 'None', 'True'])
114 KEYWORDS = frozenset(keyword.kwlist + ['print', 'async']) - SINGLETONS
115 UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-'])
116 ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-'])
117 WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%'])
118 # Warn for -> function annotation operator in py3.5+ (issue 803)
119 FUNCTION_RETURN_ANNOTATION_OP = ['->'] if sys.version_info >= (3, 5) else []
120 ASSIGNMENT_EXPRESSION_OP = [':='] if sys.version_info >= (3, 8) else []
121 WS_NEEDED_OPERATORS = frozenset([
122  '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<>', '<', '>',
123  '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '=',
124  'and', 'in', 'is', 'or'] +
125  FUNCTION_RETURN_ANNOTATION_OP +
126  ASSIGNMENT_EXPRESSION_OP)
127 WHITESPACE = frozenset(' \t')
128 NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE])
129 SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT])
130 # ERRORTOKEN is triggered by backticks in Python 3
131 SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN])
132 BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines']
133 
134 INDENT_REGEX = re.compile(r'([ \t]*)')
135 RAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,')
136 RERAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,.*,\s*\w+\s*$')
137 ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b')
138 DOCSTRING_REGEX = re.compile(r'u?r?["\']')
139 EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[\[({] | [\]}),;]| :(?!=)')
140 WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?: |\t)')
141 COMPARE_SINGLETON_REGEX = re.compile(r'(\bNone|\bFalse|\bTrue)?\s*([=!]=)'
142  r'\s*(?(1)|(None|False|True))\b')
143 COMPARE_NEGATIVE_REGEX = re.compile(r'\b(not)\s+[^][)(}{ ]+\s+(in|is)\s')
144 COMPARE_TYPE_REGEX = re.compile(r'(?:[=!]=|is(?:\s+not)?)\s+type(?:s.\w+Type'
145  r'|\s*\(\s*([^)]*[^ )])\s*\))')
146 KEYWORD_REGEX = re.compile(r'(\s*)\b(?:%s)\b(\s*)' % r'|'.join(KEYWORDS))
147 OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)')
148 LAMBDA_REGEX = re.compile(r'\blambda\b')
149 HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$')
150 STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)\b')
151 STARTSWITH_TOP_LEVEL_REGEX = re.compile(r'^(async\s+def\s+|def\s+|class\s+|@)')
152 STARTSWITH_INDENT_STATEMENT_REGEX = re.compile(
153  r'^\s*({0})\b'.format('|'.join(s.replace(' ', r'\s+') for s in (
154  'def', 'async def',
155  'for', 'async for',
156  'if', 'elif', 'else',
157  'try', 'except', 'finally',
158  'with', 'async with',
159  'class',
160  'while',
161  )))
162 )
163 DUNDER_REGEX = re.compile(r'^__([^\s]+)__ = ')
164 
165 _checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}}
166 
167 
168 def _get_parameters(function):
169  if sys.version_info >= (3, 3):
170  return [parameter.name
171  for parameter
172  in inspect.signature(function).parameters.values()
173  if parameter.kind == parameter.POSITIONAL_OR_KEYWORD]
174  else:
175  return inspect.getargspec(function)[0]
176 
177 
178 def register_check(check, codes=None):
179  """Register a new check object."""
180  def _add_check(check, kind, codes, args):
181  if check in _checks[kind]:
182  _checks[kind][check][0].extend(codes or [])
183  else:
184  _checks[kind][check] = (codes or [''], args)
185  if inspect.isfunction(check):
186  args = _get_parameters(check)
187  if args and args[0] in ('physical_line', 'logical_line'):
188  if codes is None:
189  codes = ERRORCODE_REGEX.findall(check.__doc__ or '')
190  _add_check(check, args[0], codes, args)
191  elif inspect.isclass(check):
192  if _get_parameters(check.__init__)[:2] == ['self', 'tree']:
193  _add_check(check, 'tree', codes, None)
194  return check
195 
196 
197 
200 
201 @register_check
202 def tabs_or_spaces(physical_line, indent_char):
203  r"""Never mix tabs and spaces.
204 
205  The most popular way of indenting Python is with spaces only. The
206  second-most popular way is with tabs only. Code indented with a
207  mixture of tabs and spaces should be converted to using spaces
208  exclusively. When invoking the Python command line interpreter with
209  the -t option, it issues warnings about code that illegally mixes
210  tabs and spaces. When using -tt these warnings become errors.
211  These options are highly recommended!
212 
213  Okay: if a == 0:\n a = 1\n b = 1
214  E101: if a == 0:\n a = 1\n\tb = 1
215  """
216  indent = INDENT_REGEX.match(physical_line).group(1)
217  for offset, char in enumerate(indent):
218  if char != indent_char:
219  return offset, "E101 indentation contains mixed spaces and tabs"
220 
221 
222 @register_check
223 def tabs_obsolete(physical_line):
224  r"""On new projects, spaces-only are strongly recommended over tabs.
225 
226  Okay: if True:\n return
227  W191: if True:\n\treturn
228  """
229  indent = INDENT_REGEX.match(physical_line).group(1)
230  if '\t' in indent:
231  return indent.index('\t'), "W191 indentation contains tabs"
232 
233 
234 @register_check
235 def trailing_whitespace(physical_line):
236  r"""Trailing whitespace is superfluous.
237 
238  The warning returned varies on whether the line itself is blank,
239  for easier filtering for those who want to indent their blank lines.
240 
241  Okay: spam(1)\n#
242  W291: spam(1) \n#
243  W293: class Foo(object):\n \n bang = 12
244  """
245  physical_line = physical_line.rstrip('\n') # chr(10), newline
246  physical_line = physical_line.rstrip('\r') # chr(13), carriage return
247  physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L
248  stripped = physical_line.rstrip(' \t\v')
249  if physical_line != stripped:
250  if stripped:
251  return len(stripped), "W291 trailing whitespace"
252  else:
253  return 0, "W293 blank line contains whitespace"
254 
255 
256 @register_check
257 def trailing_blank_lines(physical_line, lines, line_number, total_lines):
258  r"""Trailing blank lines are superfluous.
259 
260  Okay: spam(1)
261  W391: spam(1)\n
262 
263  However the last line should end with a new line (warning W292).
264  """
265  if line_number == total_lines:
266  stripped_last_line = physical_line.rstrip()
267  if physical_line and not stripped_last_line:
268  return 0, "W391 blank line at end of file"
269  if stripped_last_line == physical_line:
270  return len(lines[-1]), "W292 no newline at end of file"
271 
272 
273 @register_check
274 def maximum_line_length(physical_line, max_line_length, multiline,
275  line_number, noqa):
276  r"""Limit all lines to a maximum of 79 characters.
277 
278  There are still many devices around that are limited to 80 character
279  lines; plus, limiting windows to 80 characters makes it possible to
280  have several windows side-by-side. The default wrapping on such
281  devices looks ugly. Therefore, please limit all lines to a maximum
282  of 79 characters. For flowing long blocks of text (docstrings or
283  comments), limiting the length to 72 characters is recommended.
284 
285  Reports error E501.
286  """
287  line = physical_line.rstrip()
288  length = len(line)
289  if length > max_line_length and not noqa:
290  # Special case: ignore long shebang lines.
291  if line_number == 1 and line.startswith('#!'):
292  return
293  # Special case for long URLs in multi-line docstrings or
294  # comments, but still report the error when the 72 first chars
295  # are whitespaces.
296  chunks = line.split()
297  if ((len(chunks) == 1 and multiline) or
298  (len(chunks) == 2 and chunks[0] == '#')) and \
299  len(line) - len(chunks[-1]) < max_line_length - 7:
300  return
301  if hasattr(line, 'decode'): # Python 2
302  # The line could contain multi-byte characters
303  try:
304  length = len(line.decode('utf-8'))
305  except UnicodeError:
306  pass
307  if length > max_line_length:
308  return (max_line_length, "E501 line too long "
309  "(%d > %d characters)" % (length, max_line_length))
310 
311 
312 
315 
316 
317 @register_check
318 def blank_lines(logical_line, blank_lines, indent_level, line_number,
319  blank_before, previous_logical,
320  previous_unindented_logical_line, previous_indent_level,
321  lines):
322  r"""Separate top-level function and class definitions with two blank
323  lines.
324 
325  Method definitions inside a class are separated by a single blank
326  line.
327 
328  Extra blank lines may be used (sparingly) to separate groups of
329  related functions. Blank lines may be omitted between a bunch of
330  related one-liners (e.g. a set of dummy implementations).
331 
332  Use blank lines in functions, sparingly, to indicate logical
333  sections.
334 
335  Okay: def a():\n pass\n\n\ndef b():\n pass
336  Okay: def a():\n pass\n\n\nasync def b():\n pass
337  Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass
338  Okay: default = 1\nfoo = 1
339  Okay: classify = 1\nfoo = 1
340 
341  E301: class Foo:\n b = 0\n def bar():\n pass
342  E302: def a():\n pass\n\ndef b(n):\n pass
343  E302: def a():\n pass\n\nasync def b(n):\n pass
344  E303: def a():\n pass\n\n\n\ndef b(n):\n pass
345  E303: def a():\n\n\n\n pass
346  E304: @decorator\n\ndef a():\n pass
347  E305: def a():\n pass\na()
348  E306: def a():\n def b():\n pass\n def c():\n pass
349  """ # noqa
350  top_level_lines = BLANK_LINES_CONFIG['top_level']
351  method_lines = BLANK_LINES_CONFIG['method']
352 
353  if line_number < top_level_lines + 1 and not previous_logical:
354  return # Don't expect blank lines before the first line
355  if previous_logical.startswith('@'):
356  if blank_lines:
357  yield 0, "E304 blank lines found after function decorator"
358  elif (blank_lines > top_level_lines or
359  (indent_level and blank_lines == method_lines + 1)
360  ):
361  yield 0, "E303 too many blank lines (%d)" % blank_lines
362  elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line):
363  # If this is a one-liner (i.e. this is not a decorator and the
364  # next line is not more indented), and the previous line is also
365  # not deeper (it would be better to check if the previous line
366  # is part of another def/class at the same level), don't require
367  # blank lines around this.
368  prev_line = lines[line_number - 2] if line_number >= 2 else ''
369  next_line = lines[line_number] if line_number < len(lines) else ''
370  if (not logical_line.startswith("@") and
371  expand_indent(prev_line) <= indent_level and
372  expand_indent(next_line) <= indent_level):
373  return
374  if indent_level:
375  if not (blank_before == method_lines or
376  previous_indent_level < indent_level or
377  DOCSTRING_REGEX.match(previous_logical)
378  ):
379  ancestor_level = indent_level
380  nested = False
381  # Search backwards for a def ancestor or tree root
382  # (top level).
383  for line in lines[line_number - top_level_lines::-1]:
384  if line.strip() and expand_indent(line) < ancestor_level:
385  ancestor_level = expand_indent(line)
386  nested = line.lstrip().startswith('def ')
387  if nested or ancestor_level == 0:
388  break
389  if nested:
390  yield 0, "E306 expected %s blank line before a " \
391  "nested definition, found 0" % (method_lines,)
392  else:
393  yield 0, "E301 expected %s blank line, found 0" % (
394  method_lines,)
395  elif blank_before != top_level_lines:
396  yield 0, "E302 expected %s blank lines, found %d" % (
397  top_level_lines, blank_before)
398  elif (logical_line and
399  not indent_level and
400  blank_before != top_level_lines and
401  previous_unindented_logical_line.startswith(('def ', 'class '))
402  ):
403  yield 0, "E305 expected %s blank lines after " \
404  "class or function definition, found %d" % (
405  top_level_lines, blank_before)
406 
407 
408 @register_check
409 def extraneous_whitespace(logical_line):
410  r"""Avoid extraneous whitespace.
411 
412  Avoid extraneous whitespace in these situations:
413  - Immediately inside parentheses, brackets or braces.
414  - Immediately before a comma, semicolon, or colon.
415 
416  Okay: spam(ham[1], {eggs: 2})
417  E201: spam( ham[1], {eggs: 2})
418  E201: spam(ham[ 1], {eggs: 2})
419  E201: spam(ham[1], { eggs: 2})
420  E202: spam(ham[1], {eggs: 2} )
421  E202: spam(ham[1 ], {eggs: 2})
422  E202: spam(ham[1], {eggs: 2 })
423 
424  E203: if x == 4: print x, y; x, y = y , x
425  E203: if x == 4: print x, y ; x, y = y, x
426  E203: if x == 4 : print x, y; x, y = y, x
427  """
428  line = logical_line
429  for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line):
430  text = match.group()
431  char = text.strip()
432  found = match.start()
433  if text == char + ' ':
434  # assert char in '([{'
435  yield found + 1, "E201 whitespace after '%s'" % char
436  elif line[found - 1] != ',':
437  code = ('E202' if char in '}])' else 'E203') # if char in ',;:'
438  yield found, "%s whitespace before '%s'" % (code, char)
439 
440 
441 @register_check
442 def whitespace_around_keywords(logical_line):
443  r"""Avoid extraneous whitespace around keywords.
444 
445  Okay: True and False
446  E271: True and False
447  E272: True and False
448  E273: True and\tFalse
449  E274: True\tand False
450  """
451  for match in KEYWORD_REGEX.finditer(logical_line):
452  before, after = match.groups()
453 
454  if '\t' in before:
455  yield match.start(1), "E274 tab before keyword"
456  elif len(before) > 1:
457  yield match.start(1), "E272 multiple spaces before keyword"
458 
459  if '\t' in after:
460  yield match.start(2), "E273 tab after keyword"
461  elif len(after) > 1:
462  yield match.start(2), "E271 multiple spaces after keyword"
463 
464 
465 @register_check
467  r"""Multiple imports in form from x import (a, b, c) should have
468  space between import statement and parenthesised name list.
469 
470  Okay: from foo import (bar, baz)
471  E275: from foo import(bar, baz)
472  E275: from importable.module import(bar, baz)
473  """
474  line = logical_line
475  indicator = ' import('
476  if line.startswith('from '):
477  found = line.find(indicator)
478  if -1 < found:
479  pos = found + len(indicator) - 1
480  yield pos, "E275 missing whitespace after keyword"
481 
482 
483 @register_check
484 def missing_whitespace(logical_line):
485  r"""Each comma, semicolon or colon should be followed by whitespace.
486 
487  Okay: [a, b]
488  Okay: (3,)
489  Okay: a[1:4]
490  Okay: a[:4]
491  Okay: a[1:]
492  Okay: a[1:4:2]
493  E231: ['a','b']
494  E231: foo(bar,baz)
495  E231: [{'a':'b'}]
496  """
497  line = logical_line
498  for index in range(len(line) - 1):
499  char = line[index]
500  next_char = line[index + 1]
501  if char in ',;:' and next_char not in WHITESPACE:
502  before = line[:index]
503  if char == ':' and before.count('[') > before.count(']') and \
504  before.rfind('{') < before.rfind('['):
505  continue # Slice syntax, no space required
506  if char == ',' and next_char == ')':
507  continue # Allow tuple with only one element: (3,)
508  if char == ':' and next_char == '=' and sys.version_info >= (3, 8):
509  continue # Allow assignment expression
510  yield index, "E231 missing whitespace after '%s'" % char
511 
512 
513 @register_check
514 def indentation(logical_line, previous_logical, indent_char,
515  indent_level, previous_indent_level):
516  r"""Use 4 spaces per indentation level.
517 
518  For really old code that you don't want to mess up, you can continue
519  to use 8-space tabs.
520 
521  Okay: a = 1
522  Okay: if a == 0:\n a = 1
523  E111: a = 1
524  E114: # a = 1
525 
526  Okay: for item in items:\n pass
527  E112: for item in items:\npass
528  E115: for item in items:\n# Hi\n pass
529 
530  Okay: a = 1\nb = 2
531  E113: a = 1\n b = 2
532  E116: a = 1\n # b = 2
533  """
534  c = 0 if logical_line else 3
535  tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)"
536  if indent_level % 4:
537  yield 0, tmpl % (1 + c, "indentation is not a multiple of four")
538  indent_expect = previous_logical.endswith(':')
539  if indent_expect and indent_level <= previous_indent_level:
540  yield 0, tmpl % (2 + c, "expected an indented block")
541  elif not indent_expect and indent_level > previous_indent_level:
542  yield 0, tmpl % (3 + c, "unexpected indentation")
543 
544  if indent_expect:
545  expected_indent_amount = 8 if indent_char == '\t' else 4
546  expected_indent_level = previous_indent_level + expected_indent_amount
547  if indent_level > expected_indent_level:
548  yield 0, tmpl % (7, 'over-indented')
549 
550 
551 @register_check
552 def continued_indentation(logical_line, tokens, indent_level, hang_closing,
553  indent_char, noqa, verbose):
554  r"""Continuation lines indentation.
555 
556  Continuation lines should align wrapped elements either vertically
557  using Python's implicit line joining inside parentheses, brackets
558  and braces, or using a hanging indent.
559 
560  When using a hanging indent these considerations should be applied:
561  - there should be no arguments on the first line, and
562  - further indentation should be used to clearly distinguish itself
563  as a continuation line.
564 
565  Okay: a = (\n)
566  E123: a = (\n )
567 
568  Okay: a = (\n 42)
569  E121: a = (\n 42)
570  E122: a = (\n42)
571  E123: a = (\n 42\n )
572  E124: a = (24,\n 42\n)
573  E125: if (\n b):\n pass
574  E126: a = (\n 42)
575  E127: a = (24,\n 42)
576  E128: a = (24,\n 42)
577  E129: if (a or\n b):\n pass
578  E131: a = (\n 42\n 24)
579  """
580  first_row = tokens[0][2][0]
581  nrows = 1 + tokens[-1][2][0] - first_row
582  if noqa or nrows == 1:
583  return
584 
585  # indent_next tells us whether the next block is indented; assuming
586  # that it is indented by 4 spaces, then we should not allow 4-space
587  # indents on the final continuation line; in turn, some other
588  # indents are allowed to have an extra 4 spaces.
589  indent_next = logical_line.endswith(':')
590 
591  row = depth = 0
592  valid_hangs = (4,) if indent_char != '\t' else (4, 8)
593  # remember how many brackets were opened on each line
594  parens = [0] * nrows
595  # relative indents of physical lines
596  rel_indent = [0] * nrows
597  # for each depth, collect a list of opening rows
598  open_rows = [[0]]
599  # for each depth, memorize the hanging indentation
600  hangs = [None]
601  # visual indents
602  indent_chances = {}
603  last_indent = tokens[0][2]
604  visual_indent = None
605  last_token_multiline = False
606  # for each depth, memorize the visual indent column
607  indent = [last_indent[1]]
608  if verbose >= 3:
609  print(">>> " + tokens[0][4].rstrip())
610 
611  for token_type, text, start, end, line in tokens:
612 
613  newline = row < start[0] - first_row
614  if newline:
615  row = start[0] - first_row
616  newline = not last_token_multiline and token_type not in NEWLINE
617 
618  if newline:
619  # this is the beginning of a continuation line.
620  last_indent = start
621  if verbose >= 3:
622  print("... " + line.rstrip())
623 
624  # record the initial indent.
625  rel_indent[row] = expand_indent(line) - indent_level
626 
627  # identify closing bracket
628  close_bracket = (token_type == tokenize.OP and text in ']})')
629 
630  # is the indent relative to an opening bracket line?
631  for open_row in reversed(open_rows[depth]):
632  hang = rel_indent[row] - rel_indent[open_row]
633  hanging_indent = hang in valid_hangs
634  if hanging_indent:
635  break
636  if hangs[depth]:
637  hanging_indent = (hang == hangs[depth])
638  # is there any chance of visual indent?
639  visual_indent = (not close_bracket and hang > 0 and
640  indent_chances.get(start[1]))
641 
642  if close_bracket and indent[depth]:
643  # closing bracket for visual indent
644  if start[1] != indent[depth]:
645  yield (start, "E124 closing bracket does not match "
646  "visual indentation")
647  elif close_bracket and not hang:
648  # closing bracket matches indentation of opening
649  # bracket's line
650  if hang_closing:
651  yield start, "E133 closing bracket is missing indentation"
652  elif indent[depth] and start[1] < indent[depth]:
653  if visual_indent is not True:
654  # visual indent is broken
655  yield (start, "E128 continuation line "
656  "under-indented for visual indent")
657  elif hanging_indent or (indent_next and rel_indent[row] == 8):
658  # hanging indent is verified
659  if close_bracket and not hang_closing:
660  yield (start, "E123 closing bracket does not match "
661  "indentation of opening bracket's line")
662  hangs[depth] = hang
663  elif visual_indent is True:
664  # visual indent is verified
665  indent[depth] = start[1]
666  elif visual_indent in (text, str):
667  # ignore token lined up with matching one from a
668  # previous line
669  pass
670  else:
671  # indent is broken
672  if hang <= 0:
673  error = "E122", "missing indentation or outdented"
674  elif indent[depth]:
675  error = "E127", "over-indented for visual indent"
676  elif not close_bracket and hangs[depth]:
677  error = "E131", "unaligned for hanging indent"
678  else:
679  hangs[depth] = hang
680  if hang > 4:
681  error = "E126", "over-indented for hanging indent"
682  else:
683  error = "E121", "under-indented for hanging indent"
684  yield start, "%s continuation line %s" % error
685 
686  # look for visual indenting
687  if (parens[row] and
688  token_type not in (tokenize.NL, tokenize.COMMENT) and
689  not indent[depth]):
690  indent[depth] = start[1]
691  indent_chances[start[1]] = True
692  if verbose >= 4:
693  print("bracket depth %s indent to %s" % (depth, start[1]))
694  # deal with implicit string concatenation
695  elif (token_type in (tokenize.STRING, tokenize.COMMENT) or
696  text in ('u', 'ur', 'b', 'br')):
697  indent_chances[start[1]] = str
698  # special case for the "if" statement because len("if (") == 4
699  elif not indent_chances and not row and not depth and text == 'if':
700  indent_chances[end[1] + 1] = True
701  elif text == ':' and line[end[1]:].isspace():
702  open_rows[depth].append(row)
703 
704  # keep track of bracket depth
705  if token_type == tokenize.OP:
706  if text in '([{':
707  depth += 1
708  indent.append(0)
709  hangs.append(None)
710  if len(open_rows) == depth:
711  open_rows.append([])
712  open_rows[depth].append(row)
713  parens[row] += 1
714  if verbose >= 4:
715  print("bracket depth %s seen, col %s, visual min = %s" %
716  (depth, start[1], indent[depth]))
717  elif text in ')]}' and depth > 0:
718  # parent indents should not be more than this one
719  prev_indent = indent.pop() or last_indent[1]
720  hangs.pop()
721  for d in range(depth):
722  if indent[d] > prev_indent:
723  indent[d] = 0
724  for ind in list(indent_chances):
725  if ind >= prev_indent:
726  del indent_chances[ind]
727  del open_rows[depth + 1:]
728  depth -= 1
729  if depth:
730  indent_chances[indent[depth]] = True
731  for idx in range(row, -1, -1):
732  if parens[idx]:
733  parens[idx] -= 1
734  break
735  assert len(indent) == depth + 1
736  if start[1] not in indent_chances:
737  # allow lining up tokens
738  indent_chances[start[1]] = text
739 
740  last_token_multiline = (start[0] != end[0])
741  if last_token_multiline:
742  rel_indent[end[0] - first_row] = rel_indent[row]
743 
744  if indent_next and expand_indent(line) == indent_level + 4:
745  pos = (start[0], indent[0] + 4)
746  if visual_indent:
747  code = "E129 visually indented line"
748  else:
749  code = "E125 continuation line"
750  yield pos, "%s with same indent as next logical line" % code
751 
752 
753 @register_check
754 def whitespace_before_parameters(logical_line, tokens):
755  r"""Avoid extraneous whitespace.
756 
757  Avoid extraneous whitespace in the following situations:
758  - before the open parenthesis that starts the argument list of a
759  function call.
760  - before the open parenthesis that starts an indexing or slicing.
761 
762  Okay: spam(1)
763  E211: spam (1)
764 
765  Okay: dict['key'] = list[index]
766  E211: dict ['key'] = list[index]
767  E211: dict['key'] = list [index]
768  """
769  prev_type, prev_text, __, prev_end, __ = tokens[0]
770  for index in range(1, len(tokens)):
771  token_type, text, start, end, __ = tokens[index]
772  if (token_type == tokenize.OP and
773  text in '([' and
774  start != prev_end and
775  (prev_type == tokenize.NAME or prev_text in '}])') and
776  # Syntax "class A (B):" is allowed, but avoid it
777  (index < 2 or tokens[index - 2][1] != 'class') and
778  # Allow "return (a.foo for a in range(5))"
779  not keyword.iskeyword(prev_text)):
780  yield prev_end, "E211 whitespace before '%s'" % text
781  prev_type = token_type
782  prev_text = text
783  prev_end = end
784 
785 
786 @register_check
787 def whitespace_around_operator(logical_line):
788  r"""Avoid extraneous whitespace around an operator.
789 
790  Okay: a = 12 + 3
791  E221: a = 4 + 5
792  E222: a = 4 + 5
793  E223: a = 4\t+ 5
794  E224: a = 4 +\t5
795  """
796  for match in OPERATOR_REGEX.finditer(logical_line):
797  before, after = match.groups()
798 
799  if '\t' in before:
800  yield match.start(1), "E223 tab before operator"
801  elif len(before) > 1:
802  yield match.start(1), "E221 multiple spaces before operator"
803 
804  if '\t' in after:
805  yield match.start(2), "E224 tab after operator"
806  elif len(after) > 1:
807  yield match.start(2), "E222 multiple spaces after operator"
808 
809 
810 @register_check
811 def missing_whitespace_around_operator(logical_line, tokens):
812  r"""Surround operators with a single space on either side.
813 
814  - Always surround these binary operators with a single space on
815  either side: assignment (=), augmented assignment (+=, -= etc.),
816  comparisons (==, <, >, !=, <=, >=, in, not in, is, is not),
817  Booleans (and, or, not).
818 
819  - If operators with different priorities are used, consider adding
820  whitespace around the operators with the lowest priorities.
821 
822  Okay: i = i + 1
823  Okay: submitted += 1
824  Okay: x = x * 2 - 1
825  Okay: hypot2 = x * x + y * y
826  Okay: c = (a + b) * (a - b)
827  Okay: foo(bar, key='word', *args, **kwargs)
828  Okay: alpha[:-i]
829 
830  E225: i=i+1
831  E225: submitted +=1
832  E225: x = x /2 - 1
833  E225: z = x **y
834  E225: z = 1and 1
835  E226: c = (a+b) * (a-b)
836  E226: hypot2 = x*x + y*y
837  E227: c = a|b
838  E228: msg = fmt%(errno, errmsg)
839  """
840  parens = 0
841  need_space = False
842  prev_type = tokenize.OP
843  prev_text = prev_end = None
844  operator_types = (tokenize.OP, tokenize.NAME)
845  for token_type, text, start, end, line in tokens:
846  if token_type in SKIP_COMMENTS:
847  continue
848  if text in ('(', 'lambda'):
849  parens += 1
850  elif text == ')':
851  parens -= 1
852  if need_space:
853  if start != prev_end:
854  # Found a (probably) needed space
855  if need_space is not True and not need_space[1]:
856  yield (need_space[0],
857  "E225 missing whitespace around operator")
858  need_space = False
859  elif text == '>' and prev_text in ('<', '-'):
860  # Tolerate the "<>" operator, even if running Python 3
861  # Deal with Python 3's annotated return value "->"
862  pass
863  elif prev_text == '/' and text == ',':
864  # Tolerate the "/" operator in function definition
865  # For more info see PEP570
866  pass
867  else:
868  if need_space is True or need_space[1]:
869  # A needed trailing space was not found
870  yield prev_end, "E225 missing whitespace around operator"
871  elif prev_text != '**':
872  code, optype = 'E226', 'arithmetic'
873  if prev_text == '%':
874  code, optype = 'E228', 'modulo'
875  elif prev_text not in ARITHMETIC_OP:
876  code, optype = 'E227', 'bitwise or shift'
877  yield (need_space[0], "%s missing whitespace "
878  "around %s operator" % (code, optype))
879  need_space = False
880  elif token_type in operator_types and prev_end is not None:
881  if text == '=' and parens:
882  # Allow keyword args or defaults: foo(bar=None).
883  pass
884  elif text in WS_NEEDED_OPERATORS:
885  need_space = True
886  elif text in UNARY_OPERATORS:
887  # Check if the operator is used as a binary operator
888  # Allow unary operators: -123, -x, +1.
889  # Allow argument unpacking: foo(*args, **kwargs).
890  if (prev_text in '}])' if prev_type == tokenize.OP
891  else prev_text not in KEYWORDS):
892  need_space = None
893  elif text in WS_OPTIONAL_OPERATORS:
894  need_space = None
895 
896  if need_space is None:
897  # Surrounding space is optional, but ensure that
898  # trailing space matches opening space
899  need_space = (prev_end, start != prev_end)
900  elif need_space and start == prev_end:
901  # A needed opening space was not found
902  yield prev_end, "E225 missing whitespace around operator"
903  need_space = False
904  prev_type = token_type
905  prev_text = text
906  prev_end = end
907 
908 
909 @register_check
910 def whitespace_around_comma(logical_line):
911  r"""Avoid extraneous whitespace after a comma or a colon.
912 
913  Note: these checks are disabled by default
914 
915  Okay: a = (1, 2)
916  E241: a = (1, 2)
917  E242: a = (1,\t2)
918  """
919  line = logical_line
920  for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line):
921  found = m.start() + 1
922  if '\t' in m.group():
923  yield found, "E242 tab after '%s'" % m.group()[0]
924  else:
925  yield found, "E241 multiple spaces after '%s'" % m.group()[0]
926 
927 
928 @register_check
930  r"""Don't use spaces around the '=' sign in function arguments.
931 
932  Don't use spaces around the '=' sign when used to indicate a
933  keyword argument or a default parameter value, except when
934  using a type annotation.
935 
936  Okay: def complex(real, imag=0.0):
937  Okay: return magic(r=real, i=imag)
938  Okay: boolean(a == b)
939  Okay: boolean(a != b)
940  Okay: boolean(a <= b)
941  Okay: boolean(a >= b)
942  Okay: def foo(arg: int = 42):
943  Okay: async def foo(arg: int = 42):
944 
945  E251: def complex(real, imag = 0.0):
946  E251: return magic(r = real, i = imag)
947  E252: def complex(real, image: float=0.0):
948  """
949  parens = 0
950  no_space = False
951  require_space = False
952  prev_end = None
953  annotated_func_arg = False
954  in_def = bool(STARTSWITH_DEF_REGEX.match(logical_line))
955 
956  message = "E251 unexpected spaces around keyword / parameter equals"
957  missing_message = "E252 missing whitespace around parameter equals"
958 
959  for token_type, text, start, end, line in tokens:
960  if token_type == tokenize.NL:
961  continue
962  if no_space:
963  no_space = False
964  if start != prev_end:
965  yield (prev_end, message)
966  if require_space:
967  require_space = False
968  if start == prev_end:
969  yield (prev_end, missing_message)
970  if token_type == tokenize.OP:
971  if text in '([':
972  parens += 1
973  elif text in ')]':
974  parens -= 1
975  elif in_def and text == ':' and parens == 1:
976  annotated_func_arg = True
977  elif parens == 1 and text == ',':
978  annotated_func_arg = False
979  elif parens and text == '=':
980  if annotated_func_arg and parens == 1:
981  require_space = True
982  if start == prev_end:
983  yield (prev_end, missing_message)
984  else:
985  no_space = True
986  if start != prev_end:
987  yield (prev_end, message)
988  if not parens:
989  annotated_func_arg = False
990 
991  prev_end = end
992 
993 
994 @register_check
995 def whitespace_before_comment(logical_line, tokens):
996  r"""Separate inline comments by at least two spaces.
997 
998  An inline comment is a comment on the same line as a statement.
999  Inline comments should be separated by at least two spaces from the
1000  statement. They should start with a # and a single space.
1001 
1002  Each line of a block comment starts with a # and a single space
1003  (unless it is indented text inside the comment).
1004 
1005  Okay: x = x + 1 # Increment x
1006  Okay: x = x + 1 # Increment x
1007  Okay: # Block comment
1008  E261: x = x + 1 # Increment x
1009  E262: x = x + 1 #Increment x
1010  E262: x = x + 1 # Increment x
1011  E265: #Block comment
1012  E266: ### Block comment
1013  """
1014  prev_end = (0, 0)
1015  for token_type, text, start, end, line in tokens:
1016  if token_type == tokenize.COMMENT:
1017  inline_comment = line[:start[1]].strip()
1018  if inline_comment:
1019  if prev_end[0] == start[0] and start[1] < prev_end[1] + 2:
1020  yield (prev_end,
1021  "E261 at least two spaces before inline comment")
1022  symbol, sp, comment = text.partition(' ')
1023  bad_prefix = symbol not in '#:' and (symbol.lstrip('#')[:1] or '#')
1024  if inline_comment:
1025  if bad_prefix or comment[:1] in WHITESPACE:
1026  yield start, "E262 inline comment should start with '# '"
1027  elif bad_prefix and (bad_prefix != '!' or start[0] > 1):
1028  if bad_prefix != '#':
1029  yield start, "E265 block comment should start with '# '"
1030  elif comment:
1031  yield start, "E266 too many leading '#' for block comment"
1032  elif token_type != tokenize.NL:
1033  prev_end = end
1034 
1035 
1036 @register_check
1037 def imports_on_separate_lines(logical_line):
1038  r"""Place imports on separate lines.
1039 
1040  Okay: import os\nimport sys
1041  E401: import sys, os
1042 
1043  Okay: from subprocess import Popen, PIPE
1044  Okay: from myclas import MyClass
1045  Okay: from foo.bar.yourclass import YourClass
1046  Okay: import myclass
1047  Okay: import foo.bar.yourclass
1048  """
1049  line = logical_line
1050  if line.startswith('import '):
1051  found = line.find(',')
1052  if -1 < found and ';' not in line[:found]:
1053  yield found, "E401 multiple imports on one line"
1054 
1055 
1056 @register_check
1058  logical_line, indent_level, checker_state, noqa):
1059  r"""Place imports at the top of the file.
1060 
1061  Always put imports at the top of the file, just after any module
1062  comments and docstrings, and before module globals and constants.
1063 
1064  Okay: import os
1065  Okay: # this is a comment\nimport os
1066  Okay: '''this is a module docstring'''\nimport os
1067  Okay: r'''this is a module docstring'''\nimport os
1068  Okay:
1069  try:\n\timport x\nexcept ImportError:\n\tpass\nelse:\n\tpass\nimport y
1070  Okay:
1071  try:\n\timport x\nexcept ImportError:\n\tpass\nfinally:\n\tpass\nimport y
1072  E402: a=1\nimport os
1073  E402: 'One string'\n"Two string"\nimport os
1074  E402: a=1\nfrom sys import x
1075 
1076  Okay: if x:\n import os
1077  """ # noqa
1078  def is_string_literal(line):
1079  if line[0] in 'uUbB':
1080  line = line[1:]
1081  if line and line[0] in 'rR':
1082  line = line[1:]
1083  return line and (line[0] == '"' or line[0] == "'")
1084 
1085  allowed_keywords = (
1086  'try', 'except', 'else', 'finally', 'with', 'if', 'elif')
1087 
1088  if indent_level: # Allow imports in conditional statement/function
1089  return
1090  if not logical_line: # Allow empty lines or comments
1091  return
1092  if noqa:
1093  return
1094  line = logical_line
1095  if line.startswith('import ') or line.startswith('from '):
1096  if checker_state.get('seen_non_imports', False):
1097  yield 0, "E402 module level import not at top of file"
1098  elif re.match(DUNDER_REGEX, line):
1099  return
1100  elif any(line.startswith(kw) for kw in allowed_keywords):
1101  # Allow certain keywords intermixed with imports in order to
1102  # support conditional or filtered importing
1103  return
1104  elif is_string_literal(line):
1105  # The first literal is a docstring, allow it. Otherwise, report
1106  # error.
1107  if checker_state.get('seen_docstring', False):
1108  checker_state['seen_non_imports'] = True
1109  else:
1110  checker_state['seen_docstring'] = True
1111  else:
1112  checker_state['seen_non_imports'] = True
1113 
1114 
1115 @register_check
1116 def compound_statements(logical_line):
1117  r"""Compound statements (on the same line) are generally
1118  discouraged.
1119 
1120  While sometimes it's okay to put an if/for/while with a small body
1121  on the same line, never do this for multi-clause statements.
1122  Also avoid folding such long lines!
1123 
1124  Always use a def statement instead of an assignment statement that
1125  binds a lambda expression directly to a name.
1126 
1127  Okay: if foo == 'blah':\n do_blah_thing()
1128  Okay: do_one()
1129  Okay: do_two()
1130  Okay: do_three()
1131 
1132  E701: if foo == 'blah': do_blah_thing()
1133  E701: for x in lst: total += x
1134  E701: while t < 10: t = delay()
1135  E701: if foo == 'blah': do_blah_thing()
1136  E701: else: do_non_blah_thing()
1137  E701: try: something()
1138  E701: finally: cleanup()
1139  E701: if foo == 'blah': one(); two(); three()
1140  E702: do_one(); do_two(); do_three()
1141  E703: do_four(); # useless semicolon
1142  E704: def f(x): return 2*x
1143  E731: f = lambda x: 2*x
1144  """
1145  line = logical_line
1146  last_char = len(line) - 1
1147  found = line.find(':')
1148  prev_found = 0
1149  counts = {char: 0 for char in '{}[]()'}
1150  while -1 < found < last_char:
1151  update_counts(line[prev_found:found], counts)
1152  if ((counts['{'] <= counts['}'] and # {'a': 1} (dict)
1153  counts['['] <= counts[']'] and # [1:2] (slice)
1154  counts['('] <= counts[')']) and # (annotation)
1155  not (sys.version_info >= (3, 8) and
1156  line[found + 1] == '=')): # assignment expression
1157  lambda_kw = LAMBDA_REGEX.search(line, 0, found)
1158  if lambda_kw:
1159  before = line[:lambda_kw.start()].rstrip()
1160  if before[-1:] == '=' and isidentifier(before[:-1].strip()):
1161  yield 0, ("E731 do not assign a lambda expression, use a "
1162  "def")
1163  break
1164  if STARTSWITH_DEF_REGEX.match(line):
1165  yield 0, "E704 multiple statements on one line (def)"
1166  elif STARTSWITH_INDENT_STATEMENT_REGEX.match(line):
1167  yield found, "E701 multiple statements on one line (colon)"
1168  prev_found = found
1169  found = line.find(':', found + 1)
1170  found = line.find(';')
1171  while -1 < found:
1172  if found < last_char:
1173  yield found, "E702 multiple statements on one line (semicolon)"
1174  else:
1175  yield found, "E703 statement ends with a semicolon"
1176  found = line.find(';', found + 1)
1177 
1178 
1179 @register_check
1180 def explicit_line_join(logical_line, tokens):
1181  r"""Avoid explicit line join between brackets.
1182 
1183  The preferred way of wrapping long lines is by using Python's
1184  implied line continuation inside parentheses, brackets and braces.
1185  Long lines can be broken over multiple lines by wrapping expressions
1186  in parentheses. These should be used in preference to using a
1187  backslash for line continuation.
1188 
1189  E502: aaa = [123, \\n 123]
1190  E502: aaa = ("bbb " \\n "ccc")
1191 
1192  Okay: aaa = [123,\n 123]
1193  Okay: aaa = ("bbb "\n "ccc")
1194  Okay: aaa = "bbb " \\n "ccc"
1195  Okay: aaa = 123 # \\
1196  """
1197  prev_start = prev_end = parens = 0
1198  comment = False
1199  backslash = None
1200  for token_type, text, start, end, line in tokens:
1201  if token_type == tokenize.COMMENT:
1202  comment = True
1203  if start[0] != prev_start and parens and backslash and not comment:
1204  yield backslash, "E502 the backslash is redundant between brackets"
1205  if end[0] != prev_end:
1206  if line.rstrip('\r\n').endswith('\\'):
1207  backslash = (end[0], len(line.splitlines()[-1]) - 1)
1208  else:
1209  backslash = None
1210  prev_start = prev_end = end[0]
1211  else:
1212  prev_start = start[0]
1213  if token_type == tokenize.OP:
1214  if text in '([{':
1215  parens += 1
1216  elif text in ')]}':
1217  parens -= 1
1218 
1219 
1220 _SYMBOLIC_OPS = frozenset("()[]{},:.;@=%~") | frozenset(("...",))
1221 
1222 
1223 def _is_binary_operator(token_type, text):
1224  is_op_token = token_type == tokenize.OP
1225  is_conjunction = text in ['and', 'or']
1226  # NOTE(sigmavirus24): Previously the not_a_symbol check was executed
1227  # conditionally. Since it is now *always* executed, text may be
1228  # None. In that case we get a TypeError for `text not in str`.
1229  not_a_symbol = text and text not in _SYMBOLIC_OPS
1230  # The % character is strictly speaking a binary operator, but the
1231  # common usage seems to be to put it next to the format parameters,
1232  # after a line break.
1233  return ((is_op_token or is_conjunction) and not_a_symbol)
1234 
1235 
1237  """Private function to reduce duplication.
1238 
1239  This factors out the shared details between
1240  :func:`break_before_binary_operator` and
1241  :func:`break_after_binary_operator`.
1242  """
1243  line_break = False
1244  unary_context = True
1245  # Previous non-newline token types and text
1246  previous_token_type = None
1247  previous_text = None
1248  for token_type, text, start, end, line in tokens:
1249  if token_type == tokenize.COMMENT:
1250  continue
1251  if ('\n' in text or '\r' in text) and token_type != tokenize.STRING:
1252  line_break = True
1253  else:
1254  yield (token_type, text, previous_token_type, previous_text,
1255  line_break, unary_context, start)
1256  unary_context = text in '([{,;'
1257  line_break = False
1258  previous_token_type = token_type
1259  previous_text = text
1260 
1261 
1262 @register_check
1263 def break_before_binary_operator(logical_line, tokens):
1264  r"""
1265  Avoid breaks before binary operators.
1266 
1267  The preferred place to break around a binary operator is after the
1268  operator, not before it.
1269 
1270  W503: (width == 0\n + height == 0)
1271  W503: (width == 0\n and height == 0)
1272  W503: var = (1\n & ~2)
1273  W503: var = (1\n / -2)
1274  W503: var = (1\n + -1\n + -2)
1275 
1276  Okay: foo(\n -x)
1277  Okay: foo(x\n [])
1278  Okay: x = '''\n''' + ''
1279  Okay: foo(x,\n -y)
1280  Okay: foo(x, # comment\n -y)
1281  """
1282  for context in _break_around_binary_operators(tokens):
1283  (token_type, text, previous_token_type, previous_text,
1284  line_break, unary_context, start) = context
1285  if (_is_binary_operator(token_type, text) and line_break and
1286  not unary_context and
1287  not _is_binary_operator(previous_token_type,
1288  previous_text)):
1289  yield start, "W503 line break before binary operator"
1290 
1291 
1292 @register_check
1293 def break_after_binary_operator(logical_line, tokens):
1294  r"""
1295  Avoid breaks after binary operators.
1296 
1297  The preferred place to break around a binary operator is before the
1298  operator, not after it.
1299 
1300  W504: (width == 0 +\n height == 0)
1301  W504: (width == 0 and\n height == 0)
1302  W504: var = (1 &\n ~2)
1303 
1304  Okay: foo(\n -x)
1305  Okay: foo(x\n [])
1306  Okay: x = '''\n''' + ''
1307  Okay: x = '' + '''\n'''
1308  Okay: foo(x,\n -y)
1309  Okay: foo(x, # comment\n -y)
1310 
1311  The following should be W504 but unary_context is tricky with these
1312  Okay: var = (1 /\n -2)
1313  Okay: var = (1 +\n -1 +\n -2)
1314  """
1315  prev_start = None
1316  for context in _break_around_binary_operators(tokens):
1317  (token_type, text, previous_token_type, previous_text,
1318  line_break, unary_context, start) = context
1319  if (_is_binary_operator(previous_token_type, previous_text) and
1320  line_break and
1321  not unary_context and
1322  not _is_binary_operator(token_type, text)):
1323  yield prev_start, "W504 line break after binary operator"
1324  prev_start = start
1325 
1326 
1327 @register_check
1328 def comparison_to_singleton(logical_line, noqa):
1329  r"""Comparison to singletons should use "is" or "is not".
1330 
1331  Comparisons to singletons like None should always be done
1332  with "is" or "is not", never the equality operators.
1333 
1334  Okay: if arg is not None:
1335  E711: if arg != None:
1336  E711: if None == arg:
1337  E712: if arg == True:
1338  E712: if False == arg:
1339 
1340  Also, beware of writing if x when you really mean if x is not None
1341  -- e.g. when testing whether a variable or argument that defaults to
1342  None was set to some other value. The other value might have a type
1343  (such as a container) that could be false in a boolean context!
1344  """
1345  match = not noqa and COMPARE_SINGLETON_REGEX.search(logical_line)
1346  if match:
1347  singleton = match.group(1) or match.group(3)
1348  same = (match.group(2) == '==')
1349 
1350  msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton)
1351  if singleton in ('None',):
1352  code = 'E711'
1353  else:
1354  code = 'E712'
1355  nonzero = ((singleton == 'True' and same) or
1356  (singleton == 'False' and not same))
1357  msg += " or 'if %scond:'" % ('' if nonzero else 'not ')
1358  yield match.start(2), ("%s comparison to %s should be %s" %
1359  (code, singleton, msg))
1360 
1361 
1362 @register_check
1363 def comparison_negative(logical_line):
1364  r"""Negative comparison should be done using "not in" and "is not".
1365 
1366  Okay: if x not in y:\n pass
1367  Okay: assert (X in Y or X is Z)
1368  Okay: if not (X in Y):\n pass
1369  Okay: zz = x is not y
1370  E713: Z = not X in Y
1371  E713: if not X.B in Y:\n pass
1372  E714: if not X is Y:\n pass
1373  E714: Z = not X.B is Y
1374  """
1375  match = COMPARE_NEGATIVE_REGEX.search(logical_line)
1376  if match:
1377  pos = match.start(1)
1378  if match.group(2) == 'in':
1379  yield pos, "E713 test for membership should be 'not in'"
1380  else:
1381  yield pos, "E714 test for object identity should be 'is not'"
1382 
1383 
1384 @register_check
1385 def comparison_type(logical_line, noqa):
1386  r"""Object type comparisons should always use isinstance().
1387 
1388  Do not compare types directly.
1389 
1390  Okay: if isinstance(obj, int):
1391  E721: if type(obj) is type(1):
1392 
1393  When checking if an object is a string, keep in mind that it might
1394  be a unicode string too! In Python 2.3, str and unicode have a
1395  common base class, basestring, so you can do:
1396 
1397  Okay: if isinstance(obj, basestring):
1398  Okay: if type(a1) is type(b1):
1399  """
1400  match = COMPARE_TYPE_REGEX.search(logical_line)
1401  if match and not noqa:
1402  inst = match.group(1)
1403  if inst and isidentifier(inst) and inst not in SINGLETONS:
1404  return # Allow comparison for types which are not obvious
1405  yield match.start(), "E721 do not compare types, use 'isinstance()'"
1406 
1407 
1408 @register_check
1409 def bare_except(logical_line, noqa):
1410  r"""When catching exceptions, mention specific exceptions when
1411  possible.
1412 
1413  Okay: except Exception:
1414  Okay: except BaseException:
1415  E722: except:
1416  """
1417  if noqa:
1418  return
1419 
1420  regex = re.compile(r"except\s*:")
1421  match = regex.match(logical_line)
1422  if match:
1423  yield match.start(), "E722 do not use bare 'except'"
1424 
1425 
1426 @register_check
1427 def ambiguous_identifier(logical_line, tokens):
1428  r"""Never use the characters 'l', 'O', or 'I' as variable names.
1429 
1430  In some fonts, these characters are indistinguishable from the
1431  numerals one and zero. When tempted to use 'l', use 'L' instead.
1432 
1433  Okay: L = 0
1434  Okay: o = 123
1435  Okay: i = 42
1436  E741: l = 0
1437  E741: O = 123
1438  E741: I = 42
1439 
1440  Variables can be bound in several other contexts, including class
1441  and function definitions, 'global' and 'nonlocal' statements,
1442  exception handlers, and 'with' and 'for' statements.
1443  In addition, we have a special handling for function parameters.
1444 
1445  Okay: except AttributeError as o:
1446  Okay: with lock as L:
1447  Okay: foo(l=12)
1448  Okay: for a in foo(l=12):
1449  E741: except AttributeError as O:
1450  E741: with lock as l:
1451  E741: global I
1452  E741: nonlocal l
1453  E741: def foo(l):
1454  E741: def foo(l=12):
1455  E741: l = foo(l=12)
1456  E741: for l in range(10):
1457  E742: class I(object):
1458  E743: def l(x):
1459  """
1460  is_func_def = False # Set to true if 'def' is found
1461  parameter_parentheses_level = 0
1462  idents_to_avoid = ('l', 'O', 'I')
1463  prev_type, prev_text, prev_start, prev_end, __ = tokens[0]
1464  for token_type, text, start, end, line in tokens[1:]:
1465  ident = pos = None
1466  # find function definitions
1467  if prev_text == 'def':
1468  is_func_def = True
1469  # update parameter parentheses level
1470  if parameter_parentheses_level == 0 and \
1471  prev_type == tokenize.NAME and \
1472  token_type == tokenize.OP and text == '(':
1473  parameter_parentheses_level = 1
1474  elif parameter_parentheses_level > 0 and \
1475  token_type == tokenize.OP:
1476  if text == '(':
1477  parameter_parentheses_level += 1
1478  elif text == ')':
1479  parameter_parentheses_level -= 1
1480  # identifiers on the lhs of an assignment operator
1481  if token_type == tokenize.OP and '=' in text and \
1482  parameter_parentheses_level == 0:
1483  if prev_text in idents_to_avoid:
1484  ident = prev_text
1485  pos = prev_start
1486  # identifiers bound to values with 'as', 'for',
1487  # 'global', or 'nonlocal'
1488  if prev_text in ('as', 'for', 'global', 'nonlocal'):
1489  if text in idents_to_avoid:
1490  ident = text
1491  pos = start
1492  # function parameter definitions
1493  if is_func_def:
1494  if text in idents_to_avoid:
1495  ident = text
1496  pos = start
1497  if prev_text == 'class':
1498  if text in idents_to_avoid:
1499  yield start, "E742 ambiguous class definition '%s'" % text
1500  if prev_text == 'def':
1501  if text in idents_to_avoid:
1502  yield start, "E743 ambiguous function definition '%s'" % text
1503  if ident:
1504  yield pos, "E741 ambiguous variable name '%s'" % ident
1505  prev_type = token_type
1506  prev_text = text
1507  prev_start = start
1508 
1509 
1510 @register_check
1511 def python_3000_has_key(logical_line, noqa):
1512  r"""The {}.has_key() method is removed in Python 3: use the 'in'
1513  operator.
1514 
1515  Okay: if "alph" in d:\n print d["alph"]
1516  W601: assert d.has_key('alph')
1517  """
1518  pos = logical_line.find('.has_key(')
1519  if pos > -1 and not noqa:
1520  yield pos, "W601 .has_key() is deprecated, use 'in'"
1521 
1522 
1523 @register_check
1524 def python_3000_raise_comma(logical_line):
1525  r"""When raising an exception, use "raise ValueError('message')".
1526 
1527  The older form is removed in Python 3.
1528 
1529  Okay: raise DummyError("Message")
1530  W602: raise DummyError, "Message"
1531  """
1532  match = RAISE_COMMA_REGEX.match(logical_line)
1533  if match and not RERAISE_COMMA_REGEX.match(logical_line):
1534  yield match.end() - 1, "W602 deprecated form of raising exception"
1535 
1536 
1537 @register_check
1538 def python_3000_not_equal(logical_line):
1539  r"""New code should always use != instead of <>.
1540 
1541  The older syntax is removed in Python 3.
1542 
1543  Okay: if a != 'no':
1544  W603: if a <> 'no':
1545  """
1546  pos = logical_line.find('<>')
1547  if pos > -1:
1548  yield pos, "W603 '<>' is deprecated, use '!='"
1549 
1550 
1551 @register_check
1552 def python_3000_backticks(logical_line):
1553  r"""Use repr() instead of backticks in Python 3.
1554 
1555  Okay: val = repr(1 + 2)
1556  W604: val = `1 + 2`
1557  """
1558  pos = logical_line.find('`')
1559  if pos > -1:
1560  yield pos, "W604 backticks are deprecated, use 'repr()'"
1561 
1562 
1563 @register_check
1564 def python_3000_invalid_escape_sequence(logical_line, tokens, noqa):
1565  r"""Invalid escape sequences are deprecated in Python 3.6.
1566 
1567  Okay: regex = r'\.png$'
1568  W605: regex = '\.png$'
1569  """
1570  if noqa:
1571  return
1572 
1573  # https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
1574  valid = [
1575  '\n',
1576  '\\',
1577  '\'',
1578  '"',
1579  'a',
1580  'b',
1581  'f',
1582  'n',
1583  'r',
1584  't',
1585  'v',
1586  '0', '1', '2', '3', '4', '5', '6', '7',
1587  'x',
1588 
1589  # Escape sequences only recognized in string literals
1590  'N',
1591  'u',
1592  'U',
1593  ]
1594 
1595  for token_type, text, start, end, line in tokens:
1596  if token_type == tokenize.STRING:
1597  start_line, start_col = start
1598  quote = text[-3:] if text[-3:] in ('"""', "'''") else text[-1]
1599  # Extract string modifiers (e.g. u or r)
1600  quote_pos = text.index(quote)
1601  prefix = text[:quote_pos].lower()
1602  start = quote_pos + len(quote)
1603  string = text[start:-len(quote)]
1604 
1605  if 'r' not in prefix:
1606  pos = string.find('\\')
1607  while pos >= 0:
1608  pos += 1
1609  if string[pos] not in valid:
1610  line = start_line + string.count('\n', 0, pos)
1611  if line == start_line:
1612  col = start_col + len(prefix) + len(quote) + pos
1613  else:
1614  col = pos - string.rfind('\n', 0, pos) - 1
1615  yield (
1616  (line, col - 1),
1617  "W605 invalid escape sequence '\\%s'" %
1618  string[pos],
1619  )
1620  pos = string.find('\\', pos + 1)
1621 
1622 
1623 @register_check
1624 def python_3000_async_await_keywords(logical_line, tokens):
1625  """'async' and 'await' are reserved keywords starting at Python 3.7.
1626 
1627  W606: async = 42
1628  W606: await = 42
1629  Okay: async def read(db):\n data = await db.fetch('SELECT ...')
1630  """
1631  # The Python tokenize library before Python 3.5 recognizes
1632  # async/await as a NAME token. Therefore, use a state machine to
1633  # look for the possible async/await constructs as defined by the
1634  # Python grammar:
1635  # https://docs.python.org/3/reference/grammar.html
1636 
1637  state = None
1638  for token_type, text, start, end, line in tokens:
1639  error = False
1640 
1641  if token_type == tokenize.NL:
1642  continue
1643 
1644  if state is None:
1645  if token_type == tokenize.NAME:
1646  if text == 'async':
1647  state = ('async_stmt', start)
1648  elif text == 'await':
1649  state = ('await', start)
1650  elif (token_type == tokenize.NAME and
1651  text in ('def', 'for')):
1652  state = ('define', start)
1653 
1654  elif state[0] == 'async_stmt':
1655  if token_type == tokenize.NAME and text in ('def', 'with', 'for'):
1656  # One of funcdef, with_stmt, or for_stmt. Return to
1657  # looking for async/await names.
1658  state = None
1659  else:
1660  error = True
1661  elif state[0] == 'await':
1662  if token_type == tokenize.NAME:
1663  # An await expression. Return to looking for async/await
1664  # names.
1665  state = None
1666  elif token_type == tokenize.OP and text == '(':
1667  state = None
1668  else:
1669  error = True
1670  elif state[0] == 'define':
1671  if token_type == tokenize.NAME and text in ('async', 'await'):
1672  error = True
1673  else:
1674  state = None
1675 
1676  if error:
1677  yield (
1678  state[1],
1679  "W606 'async' and 'await' are reserved keywords starting with "
1680  "Python 3.7",
1681  )
1682  state = None
1683 
1684  # Last token
1685  if state is not None:
1686  yield (
1687  state[1],
1688  "W606 'async' and 'await' are reserved keywords starting with "
1689  "Python 3.7",
1690  )
1691 
1692 
1693 
1694 @register_check
1695 def maximum_doc_length(logical_line, max_doc_length, noqa, tokens):
1696  r"""Limit all doc lines to a maximum of 72 characters.
1697 
1698  For flowing long blocks of text (docstrings or comments), limiting
1699  the length to 72 characters is recommended.
1700 
1701  Reports warning W505
1702  """
1703  if max_doc_length is None or noqa:
1704  return
1705 
1706  prev_token = None
1707  skip_lines = set()
1708  # Skip lines that
1709  for token_type, text, start, end, line in tokens:
1710  if token_type not in SKIP_COMMENTS.union([tokenize.STRING]):
1711  skip_lines.add(line)
1712 
1713  for token_type, text, start, end, line in tokens:
1714  # Skip lines that aren't pure strings
1715  if token_type == tokenize.STRING and skip_lines:
1716  continue
1717  if token_type in (tokenize.STRING, tokenize.COMMENT):
1718  # Only check comment-only lines
1719  if prev_token is None or prev_token in SKIP_TOKENS:
1720  lines = line.splitlines()
1721  for line_num, physical_line in enumerate(lines):
1722  if hasattr(physical_line, 'decode'): # Python 2
1723  # The line could contain multi-byte characters
1724  try:
1725  physical_line = physical_line.decode('utf-8')
1726  except UnicodeError:
1727  pass
1728  if start[0] + line_num == 1 and line.startswith('#!'):
1729  return
1730  length = len(physical_line)
1731  chunks = physical_line.split()
1732  if token_type == tokenize.COMMENT:
1733  if (len(chunks) == 2 and
1734  length - len(chunks[-1]) < MAX_DOC_LENGTH):
1735  continue
1736  if len(chunks) == 1 and line_num + 1 < len(lines):
1737  if (len(chunks) == 1 and
1738  length - len(chunks[-1]) < MAX_DOC_LENGTH):
1739  continue
1740  if length > max_doc_length:
1741  doc_error = (start[0] + line_num, max_doc_length)
1742  yield (doc_error, "W505 doc line too long "
1743  "(%d > %d characters)"
1744  % (length, max_doc_length))
1745  prev_token = token_type
1746 
1747 
1748 
1751 
1752 
1753 if sys.version_info < (3,):
1754  # Python 2: implicit encoding.
1755  def readlines(filename):
1756  """Read the source code."""
1757  with open(filename, 'rU') as f:
1758  return f.readlines()
1759  isidentifier = re.compile(r'[a-zA-Z_]\w*$').match
1760  stdin_get_value = sys.stdin.read
1761 else:
1762  # Python 3
1763  def readlines(filename):
1764  """Read the source code."""
1765  try:
1766  with open(filename, 'rb') as f:
1767  (coding, lines) = tokenize.detect_encoding(f.readline)
1768  f = TextIOWrapper(f, coding, line_buffering=True)
1769  return [line.decode(coding) for line in lines] + f.readlines()
1770  except (LookupError, SyntaxError, UnicodeError):
1771  # Fall back if file encoding is improperly declared
1772  with open(filename, encoding='latin-1') as f:
1773  return f.readlines()
1774  isidentifier = str.isidentifier
1775 
1777  """Read the value from stdin."""
1778  return TextIOWrapper(sys.stdin.buffer, errors='ignore').read()
1779 
1780 noqa = lru_cache(512)(re.compile(r'# no(?:qa|pep8)\b', re.I).search)
1781 
1782 
1783 def expand_indent(line):
1784  r"""Return the amount of indentation.
1785 
1786  Tabs are expanded to the next multiple of 8.
1787 
1788  >>> expand_indent(' ')
1789  4
1790  >>> expand_indent('\t')
1791  8
1792  >>> expand_indent(' \t')
1793  8
1794  >>> expand_indent(' \t')
1795  16
1796  """
1797  if '\t' not in line:
1798  return len(line) - len(line.lstrip())
1799  result = 0
1800  for char in line:
1801  if char == '\t':
1802  result = result // 8 * 8 + 8
1803  elif char == ' ':
1804  result += 1
1805  else:
1806  break
1807  return result
1808 
1809 
1810 def mute_string(text):
1811  """Replace contents with 'xxx' to prevent syntax matching.
1812 
1813  >>> mute_string('"abc"')
1814  '"xxx"'
1815  >>> mute_string("'''abc'''")
1816  "'''xxx'''"
1817  >>> mute_string("r'abc'")
1818  "r'xxx'"
1819  """
1820  # String modifiers (e.g. u or r)
1821  start = text.index(text[-1]) + 1
1822  end = len(text) - 1
1823  # Triple quotes
1824  if text[-3:] in ('"""', "'''"):
1825  start += 2
1826  end -= 2
1827  return text[:start] + 'x' * (end - start) + text[end:]
1828 
1829 
1830 def parse_udiff(diff, patterns=None, parent='.'):
1831  """Return a dictionary of matching lines."""
1832  # For each file of the diff, the entry key is the filename,
1833  # and the value is a set of row numbers to consider.
1834  rv = {}
1835  path = nrows = None
1836  for line in diff.splitlines():
1837  if nrows:
1838  if line[:1] != '-':
1839  nrows -= 1
1840  continue
1841  if line[:3] == '@@ ':
1842  hunk_match = HUNK_REGEX.match(line)
1843  (row, nrows) = [int(g or '1') for g in hunk_match.groups()]
1844  rv[path].update(range(row, row + nrows))
1845  elif line[:3] == '+++':
1846  path = line[4:].split('\t', 1)[0]
1847  # Git diff will use (i)ndex, (w)ork tree, (c)ommit and
1848  # (o)bject instead of a/b/c/d as prefixes for patches
1849  if path[:2] in ('b/', 'w/', 'i/'):
1850  path = path[2:]
1851  rv[path] = set()
1852  return {
1853  os.path.join(parent, filepath): rows
1854  for (filepath, rows) in rv.items()
1855  if rows and filename_match(filepath, patterns)
1856  }
1857 
1858 
1859 def normalize_paths(value, parent=os.curdir):
1860  """Parse a comma-separated list of paths.
1861 
1862  Return a list of absolute paths.
1863  """
1864  if not value:
1865  return []
1866  if isinstance(value, list):
1867  return value
1868  paths = []
1869  for path in value.split(','):
1870  path = path.strip()
1871  if '/' in path:
1872  path = os.path.abspath(os.path.join(parent, path))
1873  paths.append(path.rstrip('/'))
1874  return paths
1875 
1876 
1877 def filename_match(filename, patterns, default=True):
1878  """Check if patterns contains a pattern that matches filename.
1879 
1880  If patterns is unspecified, this always returns True.
1881  """
1882  if not patterns:
1883  return default
1884  return any(fnmatch(filename, pattern) for pattern in patterns)
1885 
1886 
1887 def update_counts(s, counts):
1888  r"""Adds one to the counts of each appearance of characters in s,
1889  for characters in counts"""
1890  for char in s:
1891  if char in counts:
1892  counts[char] += 1
1893 
1894 
1895 def _is_eol_token(token):
1896  return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n'
1897 
1898 
1899 ########################################################################
1900 # Framework to run all checks
1901 ########################################################################
1902 
1903 
1904 class Checker(object):
1905  """Load a Python source file, tokenize it, check coding style."""
1906 
1907  def __init__(self, filename=None, lines=None,
1908  options=None, report=None, **kwargs):
1909  if options is None:
1910  options = StyleGuide(kwargs).options
1911  else:
1912  assert not kwargs
1913  self._io_error = None
1914  self._physical_checks = options.physical_checks
1915  self._logical_checks = options.logical_checks
1916  self._ast_checks = options.ast_checks
1917  self.max_line_length = options.max_line_length
1918  self.max_doc_length = options.max_doc_length
1919  self.multiline = False # in a multiline string?
1920  self.hang_closing = options.hang_closing
1921  self.verbose = options.verbose
1922  self.filename = filename
1923  # Dictionary where a checker can store its custom state.
1924  self._checker_states = {}
1925  if filename is None:
1926  self.filename = 'stdin'
1927  self.lines = lines or []
1928  elif filename == '-':
1929  self.filename = 'stdin'
1930  self.lines = stdin_get_value().splitlines(True)
1931  elif lines is None:
1932  try:
1933  self.lines = readlines(filename)
1934  except IOError:
1935  (exc_type, exc) = sys.exc_info()[:2]
1936  self._io_error = '%s: %s' % (exc_type.__name__, exc)
1937  self.lines = []
1938  else:
1939  self.lines = lines
1940  if self.lines:
1941  ord0 = ord(self.lines[0][0])
1942  if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM
1943  if ord0 == 0xfeff:
1944  self.lines[0] = self.lines[0][1:]
1945  elif self.lines[0][:3] == '\xef\xbb\xbf':
1946  self.lines[0] = self.lines[0][3:]
1947  self.report = report or options.report
1948  self.report_error = self.report.error
1949  self.noqa = False
1950 
1951  def report_invalid_syntax(self):
1952  """Check if the syntax is valid."""
1953  (exc_type, exc) = sys.exc_info()[:2]
1954  if len(exc.args) > 1:
1955  offset = exc.args[1]
1956  if len(offset) > 2:
1957  offset = offset[1:3]
1958  else:
1959  offset = (1, 0)
1960  self.report_error(offset[0], offset[1] or 0,
1961  'E901 %s: %s' % (exc_type.__name__, exc.args[0]),
1962  self.report_invalid_syntax)
1963 
1964  def readline(self):
1965  """Get the next line from the input buffer."""
1966  if self.line_number >= self.total_lines:
1967  return ''
1968  line = self.lines[self.line_number]
1969  self.line_number += 1
1970  if self.indent_char is None and line[:1] in WHITESPACE:
1971  self.indent_char = line[0]
1972  return line
1973 
1974  def run_check(self, check, argument_names):
1975  """Run a check plugin."""
1976  arguments = []
1977  for name in argument_names:
1978  arguments.append(getattr(self, name))
1979  return check(*arguments)
1980 
1981  def init_checker_state(self, name, argument_names):
1982  """Prepare custom state for the specific checker plugin."""
1983  if 'checker_state' in argument_names:
1984  self.checker_state = self._checker_states.setdefault(name, {})
1985 
1986  def check_physical(self, line):
1987  """Run all physical checks on a raw input line."""
1988  self.physical_line = line
1989  for name, check, argument_names in self._physical_checks:
1990  self.init_checker_state(name, argument_names)
1991  result = self.run_check(check, argument_names)
1992  if result is not None:
1993  (offset, text) = result
1994  self.report_error(self.line_number, offset, text, check)
1995  if text[:4] == 'E101':
1996  self.indent_char = line[0]
1997 
1998  def build_tokens_line(self):
1999  """Build a logical line from tokens."""
2000  logical = []
2001  comments = []
2002  length = 0
2003  prev_row = prev_col = mapping = None
2004  for token_type, text, start, end, line in self.tokens:
2005  if token_type in SKIP_TOKENS:
2006  continue
2007  if not mapping:
2008  mapping = [(0, start)]
2009  if token_type == tokenize.COMMENT:
2010  comments.append(text)
2011  continue
2012  if token_type == tokenize.STRING:
2013  text = mute_string(text)
2014  if prev_row:
2015  (start_row, start_col) = start
2016  if prev_row != start_row: # different row
2017  prev_text = self.lines[prev_row - 1][prev_col - 1]
2018  if prev_text == ',' or (prev_text not in '{[(' and
2019  text not in '}])'):
2020  text = ' ' + text
2021  elif prev_col != start_col: # different column
2022  text = line[prev_col:start_col] + text
2023  logical.append(text)
2024  length += len(text)
2025  mapping.append((length, end))
2026  (prev_row, prev_col) = end
2027  self.logical_line = ''.join(logical)
2028  self.noqa = comments and noqa(''.join(comments))
2029  return mapping
2030 
2031  def check_logical(self):
2032  """Build a line from tokens and run all logical checks on it."""
2033  self.report.increment_logical_line()
2034  mapping = self.build_tokens_line()
2035  if not mapping:
2036  return
2037 
2038  mapping_offsets = [offset for offset, _ in mapping]
2039  (start_row, start_col) = mapping[0][1]
2040  start_line = self.lines[start_row - 1]
2041  self.indent_level = expand_indent(start_line[:start_col])
2042  if self.blank_before < self.blank_lines:
2043  self.blank_before = self.blank_lines
2044  if self.verbose >= 2:
2045  print(self.logical_line[:80].rstrip())
2046  for name, check, argument_names in self._logical_checks:
2047  if self.verbose >= 4:
2048  print(' ' + name)
2049  self.init_checker_state(name, argument_names)
2050  for offset, text in self.run_check(check, argument_names) or ():
2051  if not isinstance(offset, tuple):
2052  # As mappings are ordered, bisecting is a fast way
2053  # to find a given offset in them.
2054  token_offset, pos = mapping[bisect.bisect_left(
2055  mapping_offsets, offset)]
2056  offset = (pos[0], pos[1] + offset - token_offset)
2057  self.report_error(offset[0], offset[1], text, check)
2058  if self.logical_line:
2059  self.previous_indent_level = self.indent_level
2060  self.previous_logical = self.logical_line
2061  if not self.indent_level:
2062  self.previous_unindented_logical_line = self.logical_line
2063  self.blank_lines = 0
2064  self.tokens = []
2065 
2066  def check_ast(self):
2067  """Build the file's AST and run all AST checks."""
2068  try:
2069  tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST)
2070  except (ValueError, SyntaxError, TypeError):
2071  return self.report_invalid_syntax()
2072  for name, cls, __ in self._ast_checks:
2073  checker = cls(tree, self.filename)
2074  for lineno, offset, text, check in checker.run():
2075  if not self.lines or not noqa(self.lines[lineno - 1]):
2076  self.report_error(lineno, offset, text, check)
2077 
2078  def generate_tokens(self):
2079  """Tokenize file, run physical line checks and yield tokens."""
2080  if self._io_error:
2081  self.report_error(1, 0, 'E902 %s' % self._io_error, readlines)
2082  tokengen = tokenize.generate_tokens(self.readline)
2083  try:
2084  for token in tokengen:
2085  if token[2][0] > self.total_lines:
2086  return
2087  self.noqa = token[4] and noqa(token[4])
2088  self.maybe_check_physical(token)
2089  yield token
2090  except (SyntaxError, tokenize.TokenError):
2091  self.report_invalid_syntax()
2092 
2093  def maybe_check_physical(self, token):
2094  """If appropriate for token, check current physical line(s)."""
2095  # Called after every token, but act only on end of line.
2096  if _is_eol_token(token):
2097  # Obviously, a newline token ends a single physical line.
2098  self.check_physical(token[4])
2099  elif token[0] == tokenize.STRING and '\n' in token[1]:
2100  # Less obviously, a string that contains newlines is a
2101  # multiline string, either triple-quoted or with internal
2102  # newlines backslash-escaped. Check every physical line in
2103  # the string *except* for the last one: its newline is
2104  # outside of the multiline string, so we consider it a
2105  # regular physical line, and will check it like any other
2106  # physical line.
2107  #
2108  # Subtleties:
2109  # - we don't *completely* ignore the last line; if it
2110  # contains the magical "# noqa" comment, we disable all
2111  # physical checks for the entire multiline string
2112  # - have to wind self.line_number back because initially it
2113  # points to the last line of the string, and we want
2114  # check_physical() to give accurate feedback
2115  if noqa(token[4]):
2116  return
2117  self.multiline = True
2118  self.line_number = token[2][0]
2119  _, src, (_, offset), _, _ = token
2120  src = self.lines[self.line_number - 1][:offset] + src
2121  for line in src.split('\n')[:-1]:
2122  self.check_physical(line + '\n')
2123  self.line_number += 1
2124  self.multiline = False
2125 
2126  def check_all(self, expected=None, line_offset=0):
2127  """Run all checks on the input file."""
2128  self.report.init_file(self.filename, self.lines, expected, line_offset)
2129  self.total_lines = len(self.lines)
2130  if self._ast_checks:
2131  self.check_ast()
2132  self.line_number = 0
2133  self.indent_char = None
2134  self.indent_level = self.previous_indent_level = 0
2135  self.previous_logical = ''
2136  self.previous_unindented_logical_line = ''
2137  self.tokens = []
2138  self.blank_lines = self.blank_before = 0
2139  parens = 0
2140  for token in self.generate_tokens():
2141  self.tokens.append(token)
2142  token_type, text = token[0:2]
2143  if self.verbose >= 3:
2144  if token[2][0] == token[3][0]:
2145  pos = '[%s:%s]' % (token[2][1] or '', token[3][1])
2146  else:
2147  pos = 'l.%s' % token[3][0]
2148  print('l.%s\t%s\t%s\t%r' %
2149  (token[2][0], pos, tokenize.tok_name[token[0]], text))
2150  if token_type == tokenize.OP:
2151  if text in '([{':
2152  parens += 1
2153  elif text in '}])':
2154  parens -= 1
2155  elif not parens:
2156  if token_type in NEWLINE:
2157  if token_type == tokenize.NEWLINE:
2158  self.check_logical()
2159  self.blank_before = 0
2160  elif len(self.tokens) == 1:
2161  # The physical line contains only this token.
2162  self.blank_lines += 1
2163  del self.tokens[0]
2164  else:
2165  self.check_logical()
2166  if self.tokens:
2167  self.check_physical(self.lines[-1])
2168  self.check_logical()
2169  return self.report.get_file_results()
2170 
2171 
2172 class BaseReport(object):
2173  """Collect the results of the checks."""
2174 
2175  print_filename = False
2176 
2177  def __init__(self, options):
2178  self._benchmark_keys = options.benchmark_keys
2179  self._ignore_code = options.ignore_code
2180  # Results
2181  self.elapsed = 0
2182  self.total_errors = 0
2183  self.counters = dict.fromkeys(self._benchmark_keys, 0)
2184  self.messages = {}
2185 
2186  def start(self):
2187  """Start the timer."""
2188  self._start_time = time.time()
2189 
2190  def stop(self):
2191  """Stop the timer."""
2192  self.elapsed = time.time() - self._start_time
2193 
2194  def init_file(self, filename, lines, expected, line_offset):
2195  """Signal a new file."""
2196  self.filename = filename
2197  self.lines = lines
2198  self.expected = expected or ()
2199  self.line_offset = line_offset
2200  self.file_errors = 0
2201  self.counters['files'] += 1
2202  self.counters['physical lines'] += len(lines)
2203 
2204  def increment_logical_line(self):
2205  """Signal a new logical line."""
2206  self.counters['logical lines'] += 1
2207 
2208  def error(self, line_number, offset, text, check):
2209  """Report an error, according to options."""
2210  code = text[:4]
2211  if self._ignore_code(code):
2212  return
2213  if code in self.counters:
2214  self.counters[code] += 1
2215  else:
2216  self.counters[code] = 1
2217  self.messages[code] = text[5:]
2218  # Don't care about expected errors or warnings
2219  if code in self.expected:
2220  return
2221  if self.print_filename and not self.file_errors:
2222  print(self.filename)
2223  self.file_errors += 1
2224  self.total_errors += 1
2225  return code
2226 
2227  def get_file_results(self):
2228  """Return the count of errors and warnings for this file."""
2229  return self.file_errors
2230 
2231  def get_count(self, prefix=''):
2232  """Return the total count of errors and warnings."""
2233  return sum(self.counters[key]
2234  for key in self.messages if key.startswith(prefix))
2235 
2236  def get_statistics(self, prefix=''):
2237  """Get statistics for message codes that start with the prefix.
2238 
2239  prefix='' matches all errors and warnings
2240  prefix='E' matches all errors
2241  prefix='W' matches all warnings
2242  prefix='E4' matches all errors that have to do with imports
2243  """
2244  return ['%-7s %s %s' % (self.counters[key], key, self.messages[key])
2245  for key in sorted(self.messages) if key.startswith(prefix)]
2246 
2247  def print_statistics(self, prefix=''):
2248  """Print overall statistics (number of errors and warnings)."""
2249  for line in self.get_statistics(prefix):
2250  print(line)
2251 
2252  def print_benchmark(self):
2253  """Print benchmark numbers."""
2254  print('%-7.2f %s' % (self.elapsed, 'seconds elapsed'))
2255  if self.elapsed:
2256  for key in self._benchmark_keys:
2257  print('%-7d %s per second (%d total)' %
2258  (self.counters[key] / self.elapsed, key,
2259  self.counters[key]))
2260 
2261 
2262 class FileReport(BaseReport):
2263  """Collect the results of the checks and print the filenames."""
2264 
2265  print_filename = True
2266 
2267 
2268 class StandardReport(BaseReport):
2269  """Collect and print the results of the checks."""
2270 
2271  def __init__(self, options):
2272  super(StandardReport, self).__init__(options)
2273  self._fmt = REPORT_FORMAT.get(options.format.lower(),
2274  options.format)
2275  self._repeat = options.repeat
2276  self._show_source = options.show_source
2277  self._show_pep8 = options.show_pep8
2278 
2279  def init_file(self, filename, lines, expected, line_offset):
2280  """Signal a new file."""
2281  self._deferred_print = []
2282  return super(StandardReport, self).init_file(
2283  filename, lines, expected, line_offset)
2284 
2285  def error(self, line_number, offset, text, check):
2286  """Report an error, according to options."""
2287  code = super(StandardReport, self).error(line_number, offset,
2288  text, check)
2289  if code and (self.counters[code] == 1 or self._repeat):
2290  self._deferred_print.append(
2291  (line_number, offset, code, text[5:], check.__doc__))
2292  return code
2293 
2294  def get_file_results(self):
2295  """Print results and return the overall count for this file."""
2296  self._deferred_print.sort()
2297  for line_number, offset, code, text, doc in self._deferred_print:
2298  print(self._fmt % {
2299  'path': self.filename,
2300  'row': self.line_offset + line_number, 'col': offset + 1,
2301  'code': code, 'text': text,
2302  })
2303  if self._show_source:
2304  if line_number > len(self.lines):
2305  line = ''
2306  else:
2307  line = self.lines[line_number - 1]
2308  print(line.rstrip())
2309  print(re.sub(r'\S', ' ', line[:offset]) + '^')
2310  if self._show_pep8 and doc:
2311  print(' ' + doc.strip())
2312 
2313  # stdout is block buffered when not stdout.isatty().
2314  # line can be broken where buffer boundary since other
2315  # processes write to same file.
2316  # flush() after print() to avoid buffer boundary.
2317  # Typical buffer size is 8192. line written safely when
2318  # len(line) < 8192.
2319  sys.stdout.flush()
2320  return self.file_errors
2321 
2322 
2323 class DiffReport(StandardReport):
2324  """Collect and print the results for the changed lines only."""
2325 
2326  def __init__(self, options):
2327  super(DiffReport, self).__init__(options)
2328  self._selected = options.selected_lines
2329 
2330  def error(self, line_number, offset, text, check):
2331  if line_number not in self._selected[self.filename]:
2332  return
2333  return super(DiffReport, self).error(line_number, offset, text, check)
2334 
2335 
2336 class StyleGuide(object):
2337  """Initialize a PEP-8 instance with few options."""
2338 
2339  def __init__(self, *args, **kwargs):
2340  # build options from the command line
2341  self.checker_class = kwargs.pop('checker_class', Checker)
2342  parse_argv = kwargs.pop('parse_argv', False)
2343  config_file = kwargs.pop('config_file', False)
2344  parser = kwargs.pop('parser', None)
2345  # build options from dict
2346  options_dict = dict(*args, **kwargs)
2347  arglist = None if parse_argv else options_dict.get('paths', None)
2348  verbose = options_dict.get('verbose', None)
2349  options, self.paths = process_options(
2350  arglist, parse_argv, config_file, parser, verbose)
2351  if options_dict:
2352  options.__dict__.update(options_dict)
2353  if 'paths' in options_dict:
2354  self.paths = options_dict['paths']
2355 
2356  self.runner = self.input_file
2357  self.options = options
2358 
2359  if not options.reporter:
2360  options.reporter = BaseReport if options.quiet else StandardReport
2361 
2362  options.select = tuple(options.select or ())
2363  if not (options.select or options.ignore or
2364  options.testsuite or options.doctest) and DEFAULT_IGNORE:
2365  # The default choice: ignore controversial checks
2366  options.ignore = tuple(DEFAULT_IGNORE.split(','))
2367  else:
2368  # Ignore all checks which are not explicitly selected
2369  options.ignore = ('',) if options.select else tuple(options.ignore)
2370  options.benchmark_keys = BENCHMARK_KEYS[:]
2371  options.ignore_code = self.ignore_code
2372  options.physical_checks = self.get_checks('physical_line')
2373  options.logical_checks = self.get_checks('logical_line')
2374  options.ast_checks = self.get_checks('tree')
2375  self.init_report()
2376 
2377  def init_report(self, reporter=None):
2378  """Initialize the report instance."""
2379  self.options.report = (reporter or self.options.reporter)(self.options)
2380  return self.options.report
2381 
2382  def check_files(self, paths=None):
2383  """Run all checks on the paths."""
2384  if paths is None:
2385  paths = self.paths
2386  report = self.options.report
2387  runner = self.runner
2388  report.start()
2389  try:
2390  for path in paths:
2391  if os.path.isdir(path):
2392  self.input_dir(path)
2393  elif not self.excluded(path):
2394  runner(path)
2395  except KeyboardInterrupt:
2396  print('... stopped')
2397  report.stop()
2398  return report
2399 
2400  def input_file(self, filename, lines=None, expected=None, line_offset=0):
2401  """Run all checks on a Python source file."""
2402  if self.options.verbose:
2403  print('checking %s' % filename)
2404  fchecker = self.checker_class(
2405  filename, lines=lines, options=self.options)
2406  return fchecker.check_all(expected=expected, line_offset=line_offset)
2407 
2408  def input_dir(self, dirname):
2409  """Check all files in this directory and all subdirectories."""
2410  dirname = dirname.rstrip('/')
2411  if self.excluded(dirname):
2412  return 0
2413  counters = self.options.report.counters
2414  verbose = self.options.verbose
2415  filepatterns = self.options.filename
2416  runner = self.runner
2417  for root, dirs, files in os.walk(dirname):
2418  if verbose:
2419  print('directory ' + root)
2420  counters['directories'] += 1
2421  for subdir in sorted(dirs):
2422  if self.excluded(subdir, root):
2423  dirs.remove(subdir)
2424  for filename in sorted(files):
2425  # contain a pattern that matches?
2426  if ((filename_match(filename, filepatterns) and
2427  not self.excluded(filename, root))):
2428  runner(os.path.join(root, filename))
2429 
2430  def excluded(self, filename, parent=None):
2431  """Check if the file should be excluded.
2432 
2433  Check if 'options.exclude' contains a pattern matching filename.
2434  """
2435  if not self.options.exclude:
2436  return False
2437  basename = os.path.basename(filename)
2438  if filename_match(basename, self.options.exclude):
2439  return True
2440  if parent:
2441  filename = os.path.join(parent, filename)
2442  filename = os.path.abspath(filename)
2443  return filename_match(filename, self.options.exclude)
2444 
2445  def ignore_code(self, code):
2446  """Check if the error code should be ignored.
2447 
2448  If 'options.select' contains a prefix of the error code,
2449  return False. Else, if 'options.ignore' contains a prefix of
2450  the error code, return True.
2451  """
2452  if len(code) < 4 and any(s.startswith(code)
2453  for s in self.options.select):
2454  return False
2455  return (code.startswith(self.options.ignore) and
2456  not code.startswith(self.options.select))
2457 
2458  def get_checks(self, argument_name):
2459  """Get all the checks for this category.
2460 
2461  Find all globally visible functions where the first argument
2462  name starts with argument_name and which contain selected tests.
2463  """
2464  checks = []
2465  for check, attrs in _checks[argument_name].items():
2466  (codes, args) = attrs
2467  if any(not (code and self.ignore_code(code)) for code in codes):
2468  checks.append((check.__name__, check, args))
2469  return sorted(checks)
2470 
2471 
2472 def get_parser(prog='pycodestyle', version=__version__):
2473  """Create the parser for the program."""
2474  parser = OptionParser(prog=prog, version=version,
2475  usage="%prog [options] input ...")
2476  parser.config_options = [
2477  'exclude', 'filename', 'select', 'ignore', 'max-line-length',
2478  'max-doc-length', 'hang-closing', 'count', 'format', 'quiet',
2479  'show-pep8', 'show-source', 'statistics', 'verbose']
2480  parser.add_option('-v', '--verbose', default=0, action='count',
2481  help="print status messages, or debug with -vv")
2482  parser.add_option('-q', '--quiet', default=0, action='count',
2483  help="report only file names, or nothing with -qq")
2484  parser.add_option('-r', '--repeat', default=True, action='store_true',
2485  help="(obsolete) show all occurrences of the same error")
2486  parser.add_option('--first', action='store_false', dest='repeat',
2487  help="show first occurrence of each error")
2488  parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE,
2489  help="exclude files or directories which match these "
2490  "comma separated patterns (default: %default)")
2491  parser.add_option('--filename', metavar='patterns', default='*.py',
2492  help="when parsing directories, only check filenames "
2493  "matching these comma separated patterns "
2494  "(default: %default)")
2495  parser.add_option('--select', metavar='errors', default='',
2496  help="select errors and warnings (e.g. E,W6)")
2497  parser.add_option('--ignore', metavar='errors', default='',
2498  help="skip errors and warnings (e.g. E4,W) "
2499  "(default: %s)" % DEFAULT_IGNORE)
2500  parser.add_option('--show-source', action='store_true',
2501  help="show source code for each error")
2502  parser.add_option('--show-pep8', action='store_true',
2503  help="show text of PEP 8 for each error "
2504  "(implies --first)")
2505  parser.add_option('--statistics', action='store_true',
2506  help="count errors and warnings")
2507  parser.add_option('--count', action='store_true',
2508  help="print total number of errors and warnings "
2509  "to standard error and set exit code to 1 if "
2510  "total is not null")
2511  parser.add_option('--max-line-length', type='int', metavar='n',
2512  default=MAX_LINE_LENGTH,
2513  help="set maximum allowed line length "
2514  "(default: %default)")
2515  parser.add_option('--max-doc-length', type='int', metavar='n',
2516  default=None,
2517  help="set maximum allowed doc line length and perform "
2518  "these checks (unchecked if not set)")
2519  parser.add_option('--hang-closing', action='store_true',
2520  help="hang closing bracket instead of matching "
2521  "indentation of opening bracket's line")
2522  parser.add_option('--format', metavar='format', default='default',
2523  help="set the error format [default|pylint|<custom>]")
2524  parser.add_option('--diff', action='store_true',
2525  help="report changes only within line number ranges in "
2526  "the unified diff received on STDIN")
2527  group = parser.add_option_group("Testing Options")
2528  if os.path.exists(TESTSUITE_PATH):
2529  group.add_option('--testsuite', metavar='dir',
2530  help="run regression tests from dir")
2531  group.add_option('--doctest', action='store_true',
2532  help="run doctest on myself")
2533  group.add_option('--benchmark', action='store_true',
2534  help="measure processing speed")
2535  return parser
2536 
2537 
2538 def read_config(options, args, arglist, parser):
2539  """Read and parse configurations.
2540 
2541  If a config file is specified on the command line with the
2542  "--config" option, then only it is used for configuration.
2543 
2544  Otherwise, the user configuration (~/.config/pycodestyle) and any
2545  local configurations in the current directory or above will be
2546  merged together (in that order) using the read method of
2547  ConfigParser.
2548  """
2549  config = RawConfigParser()
2550 
2551  cli_conf = options.config
2552 
2553  local_dir = os.curdir
2554 
2555  if USER_CONFIG and os.path.isfile(USER_CONFIG):
2556  if options.verbose:
2557  print('user configuration: %s' % USER_CONFIG)
2558  config.read(USER_CONFIG)
2559 
2560  parent = tail = args and os.path.abspath(os.path.commonprefix(args))
2561  while tail:
2562  if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG):
2563  local_dir = parent
2564  if options.verbose:
2565  print('local configuration: in %s' % parent)
2566  break
2567  (parent, tail) = os.path.split(parent)
2568 
2569  if cli_conf and os.path.isfile(cli_conf):
2570  if options.verbose:
2571  print('cli configuration: %s' % cli_conf)
2572  config.read(cli_conf)
2573 
2574  pycodestyle_section = None
2575  if config.has_section(parser.prog):
2576  pycodestyle_section = parser.prog
2577  elif config.has_section('pep8'):
2578  pycodestyle_section = 'pep8' # Deprecated
2579  warnings.warn('[pep8] section is deprecated. Use [pycodestyle].')
2580 
2581  if pycodestyle_section:
2582  option_list = {o.dest: o.type or o.action for o in parser.option_list}
2583 
2584  # First, read the default values
2585  (new_options, __) = parser.parse_args([])
2586 
2587  # Second, parse the configuration
2588  for opt in config.options(pycodestyle_section):
2589  if opt.replace('_', '-') not in parser.config_options:
2590  print(" unknown option '%s' ignored" % opt)
2591  continue
2592  if options.verbose > 1:
2593  print(" %s = %s" % (opt,
2594  config.get(pycodestyle_section, opt)))
2595  normalized_opt = opt.replace('-', '_')
2596  opt_type = option_list[normalized_opt]
2597  if opt_type in ('int', 'count'):
2598  value = config.getint(pycodestyle_section, opt)
2599  elif opt_type in ('store_true', 'store_false'):
2600  value = config.getboolean(pycodestyle_section, opt)
2601  else:
2602  value = config.get(pycodestyle_section, opt)
2603  if normalized_opt == 'exclude':
2604  value = normalize_paths(value, local_dir)
2605  setattr(new_options, normalized_opt, value)
2606 
2607  # Third, overwrite with the command-line options
2608  (options, __) = parser.parse_args(arglist, values=new_options)
2609  options.doctest = options.testsuite = False
2610  return options
2611 
2612 
2613 def process_options(arglist=None, parse_argv=False, config_file=None,
2614  parser=None, verbose=None):
2615  """Process options passed either via arglist or command line args.
2616 
2617  Passing in the ``config_file`` parameter allows other tools, such as
2618  flake8 to specify their own options to be processed in pycodestyle.
2619  """
2620  if not parser:
2621  parser = get_parser()
2622  if not parser.has_option('--config'):
2623  group = parser.add_option_group("Configuration", description=(
2624  "The project options are read from the [%s] section of the "
2625  "tox.ini file or the setup.cfg file located in any parent folder "
2626  "of the path(s) being processed. Allowed options are: %s." %
2627  (parser.prog, ', '.join(parser.config_options))))
2628  group.add_option('--config', metavar='path', default=config_file,
2629  help="user config file location")
2630  # Don't read the command line if the module is used as a library.
2631  if not arglist and not parse_argv:
2632  arglist = []
2633  # If parse_argv is True and arglist is None, arguments are
2634  # parsed from the command line (sys.argv)
2635  (options, args) = parser.parse_args(arglist)
2636  options.reporter = None
2637 
2638  # If explicitly specified verbosity, override any `-v` CLI flag
2639  if verbose is not None:
2640  options.verbose = verbose
2641 
2642  if options.ensure_value('testsuite', False):
2643  args.append(options.testsuite)
2644  elif not options.ensure_value('doctest', False):
2645  if parse_argv and not args:
2646  if options.diff or any(os.path.exists(name)
2647  for name in PROJECT_CONFIG):
2648  args = ['.']
2649  else:
2650  parser.error('input not specified')
2651  options = read_config(options, args, arglist, parser)
2652  options.reporter = parse_argv and options.quiet == 1 and FileReport
2653 
2654  options.filename = _parse_multi_options(options.filename)
2655  options.exclude = normalize_paths(options.exclude)
2656  options.select = _parse_multi_options(options.select)
2657  options.ignore = _parse_multi_options(options.ignore)
2658 
2659  if options.diff:
2660  options.reporter = DiffReport
2661  stdin = stdin_get_value()
2662  options.selected_lines = parse_udiff(stdin, options.filename, args[0])
2663  args = sorted(options.selected_lines)
2664 
2665  return options, args
2666 
2667 
2668 def _parse_multi_options(options, split_token=','):
2669  r"""Split and strip and discard empties.
2670 
2671  Turns the following:
2672 
2673  A,
2674  B,
2675 
2676  into ["A", "B"]
2677  """
2678  if options:
2679  return [o.strip() for o in options.split(split_token) if o.strip()]
2680  else:
2681  return options
2682 
2683 
2684 def _main():
2685  """Parse options and run checks on Python source."""
2686  import signal
2687 
2688  # Handle "Broken pipe" gracefully
2689  try:
2690  signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1))
2691  except AttributeError:
2692  pass # not supported on Windows
2693 
2694  style_guide = StyleGuide(parse_argv=True)
2695  options = style_guide.options
2696 
2697  if options.doctest or options.testsuite:
2698  from testsuite.support import run_tests
2699  report = run_tests(style_guide)
2700  else:
2701  report = style_guide.check_files()
2702 
2703  if options.statistics:
2704  report.print_statistics()
2705 
2706  if options.benchmark:
2707  report.print_benchmark()
2708 
2709  if options.testsuite and not options.quiet:
2710  report.print_results()
2711 
2712  if report.total_errors:
2713  if options.count:
2714  sys.stderr.write(str(report.total_errors) + '\n')
2715  sys.exit(1)
2716 
2717 
2718 if __name__ == '__main__':
2719  _main()
def python_3000_raise_comma(logical_line)
def expand_indent(line)
def comparison_negative(logical_line)
def whitespace_before_parameters(logical_line, tokens)
Definition: pycodestyle.py:754
def tabs_or_spaces(physical_line, indent_char)
Plugins (check functions) for physical lines.
Definition: pycodestyle.py:202
def whitespace_around_comma(logical_line)
Definition: pycodestyle.py:910
def tabs_obsolete(physical_line)
Definition: pycodestyle.py:223
def extraneous_whitespace(logical_line)
Definition: pycodestyle.py:409
def blank_lines(logical_line, blank_lines, indent_level, line_number, blank_before, previous_logical, previous_unindented_logical_line, previous_indent_level, lines)
Plugins (check functions) for logical lines.
Definition: pycodestyle.py:321
def maximum_line_length(physical_line, max_line_length, multiline, line_number, noqa)
Definition: pycodestyle.py:275
def imports_on_separate_lines(logical_line)
def trailing_blank_lines(physical_line, lines, line_number, total_lines)
Definition: pycodestyle.py:257
def _break_around_binary_operators(tokens)
def register_check(check, codes=None)
Definition: pycodestyle.py:178
def python_3000_invalid_escape_sequence(logical_line, tokens, noqa)
def whitespace_around_named_parameter_equals(logical_line, tokens)
Definition: pycodestyle.py:929
def bare_except(logical_line, noqa)
def ambiguous_identifier(logical_line, tokens)
def readlines(filename)
Helper functions.
def whitespace_around_operator(logical_line)
Definition: pycodestyle.py:787
def comparison_to_singleton(logical_line, noqa)
def trailing_whitespace(physical_line)
Definition: pycodestyle.py:235
def indentation(logical_line, previous_logical, indent_char, indent_level, previous_indent_level)
Definition: pycodestyle.py:515
def continued_indentation(logical_line, tokens, indent_level, hang_closing, indent_char, noqa, verbose)
Definition: pycodestyle.py:553
def break_before_binary_operator(logical_line, tokens)
def python_3000_async_await_keywords(logical_line, tokens)
def lru_cache(maxsize=128)
Definition: pycodestyle.py:65
def _is_binary_operator(token_type, text)
def maximum_doc_length(logical_line, max_doc_length, noqa, tokens)
def missing_whitespace_after_import_keyword(logical_line)
Definition: pycodestyle.py:466
def compound_statements(logical_line)
def missing_whitespace_around_operator(logical_line, tokens)
Definition: pycodestyle.py:811
def module_imports_on_top_of_file(logical_line, indent_level, checker_state, noqa)
def missing_whitespace(logical_line)
Definition: pycodestyle.py:484
def break_after_binary_operator(logical_line, tokens)
def comparison_type(logical_line, noqa)
def python_3000_backticks(logical_line)
def update_counts(s, counts)
def python_3000_not_equal(logical_line)
def whitespace_before_comment(logical_line, tokens)
Definition: pycodestyle.py:995
def explicit_line_join(logical_line, tokens)
def python_3000_has_key(logical_line, noqa)
def whitespace_around_keywords(logical_line)
Definition: pycodestyle.py:442
def _get_parameters(function)
Definition: pycodestyle.py:168


roslint
Author(s): Mike Purvis, Jack O'Quin
autogenerated on Sun Mar 5 2023 03:27:29