pycodestyle-2.5.0/0000775000175000017500000000000013424056203015463 5ustar icordascicordasc00000000000000pycodestyle-2.5.0/pycodestyle.py0000775000175000017500000030357113424055750020423 0ustar icordascicordasc00000000000000#!/usr/bin/env python # pycodestyle.py - Check Python source code formatting, according to # PEP 8 # # Copyright (C) 2006-2009 Johann C. Rocholl # Copyright (C) 2009-2014 Florent Xicluna # Copyright (C) 2014-2016 Ian Lee # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation files # (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. r""" Check Python source code formatting, according to PEP 8. For usage and a list of options, try this: $ python pycodestyle.py -h This program and its regression test suite live here: https://github.com/pycqa/pycodestyle Groups of errors and warnings: E errors W warnings 100 indentation 200 whitespace 300 blank lines 400 imports 500 line length 600 deprecation 700 statements 900 syntax error """ from __future__ import with_statement import inspect import keyword import os import re import sys import time import tokenize import warnings import bisect try: from functools import lru_cache except ImportError: def lru_cache(maxsize=128): # noqa as it's a fake implementation. """Does not really need a real a lru_cache, it's just optimization, so let's just do nothing here. Python 3.2+ will just get better performances, time to upgrade? """ return lambda function: function from fnmatch import fnmatch from optparse import OptionParser try: from configparser import RawConfigParser from io import TextIOWrapper except ImportError: from ConfigParser import RawConfigParser __version__ = '2.5.0' DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504' try: if sys.platform == 'win32': USER_CONFIG = os.path.expanduser(r'~\.pycodestyle') else: USER_CONFIG = os.path.join( os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'), 'pycodestyle' ) except ImportError: USER_CONFIG = None PROJECT_CONFIG = ('setup.cfg', 'tox.ini') TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite') MAX_LINE_LENGTH = 79 # Number of blank lines between various code parts. BLANK_LINES_CONFIG = { # Top level class and function. 'top_level': 2, # Methods and nested class and function. 'method': 1, } MAX_DOC_LENGTH = 72 REPORT_FORMAT = { 'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s', 'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s', } PyCF_ONLY_AST = 1024 SINGLETONS = frozenset(['False', 'None', 'True']) KEYWORDS = frozenset(keyword.kwlist + ['print', 'async']) - SINGLETONS UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-']) ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-']) WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%']) # Warn for -> function annotation operator in py3.5+ (issue 803) FUNCTION_RETURN_ANNOTATION_OP = ['->'] if sys.version_info >= (3, 5) else [] WS_NEEDED_OPERATORS = frozenset([ '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<>', '<', '>', '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '='] + FUNCTION_RETURN_ANNOTATION_OP) WHITESPACE = frozenset(' \t') NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE]) SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT]) # ERRORTOKEN is triggered by backticks in Python 3 SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN]) BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines'] INDENT_REGEX = re.compile(r'([ \t]*)') RAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,') RERAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,.*,\s*\w+\s*$') ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b') DOCSTRING_REGEX = re.compile(r'u?r?["\']') EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[\[({] | [\]}),;:]') WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?: |\t)') COMPARE_SINGLETON_REGEX = re.compile(r'(\bNone|\bFalse|\bTrue)?\s*([=!]=)' r'\s*(?(1)|(None|False|True))\b') COMPARE_NEGATIVE_REGEX = re.compile(r'\b(not)\s+[^][)(}{ ]+\s+(in|is)\s') COMPARE_TYPE_REGEX = re.compile(r'(?:[=!]=|is(?:\s+not)?)\s*type(?:s.\w+Type' r'|\s*\(\s*([^)]*[^ )])\s*\))') KEYWORD_REGEX = re.compile(r'(\s*)\b(?:%s)\b(\s*)' % r'|'.join(KEYWORDS)) OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)') LAMBDA_REGEX = re.compile(r'\blambda\b') HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$') STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)\b') STARTSWITH_TOP_LEVEL_REGEX = re.compile(r'^(async\s+def\s+|def\s+|class\s+|@)') STARTSWITH_INDENT_STATEMENT_REGEX = re.compile( r'^\s*({0})\b'.format('|'.join(s.replace(' ', r'\s+') for s in ( 'def', 'async def', 'for', 'async for', 'if', 'elif', 'else', 'try', 'except', 'finally', 'with', 'async with', 'class', 'while', ))) ) DUNDER_REGEX = re.compile(r'^__([^\s]+)__ = ') _checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}} def _get_parameters(function): if sys.version_info >= (3, 3): return [parameter.name for parameter in inspect.signature(function).parameters.values() if parameter.kind == parameter.POSITIONAL_OR_KEYWORD] else: return inspect.getargspec(function)[0] def register_check(check, codes=None): """Register a new check object.""" def _add_check(check, kind, codes, args): if check in _checks[kind]: _checks[kind][check][0].extend(codes or []) else: _checks[kind][check] = (codes or [''], args) if inspect.isfunction(check): args = _get_parameters(check) if args and args[0] in ('physical_line', 'logical_line'): if codes is None: codes = ERRORCODE_REGEX.findall(check.__doc__ or '') _add_check(check, args[0], codes, args) elif inspect.isclass(check): if _get_parameters(check.__init__)[:2] == ['self', 'tree']: _add_check(check, 'tree', codes, None) return check ######################################################################## # Plugins (check functions) for physical lines ######################################################################## @register_check def tabs_or_spaces(physical_line, indent_char): r"""Never mix tabs and spaces. The most popular way of indenting Python is with spaces only. The second-most popular way is with tabs only. Code indented with a mixture of tabs and spaces should be converted to using spaces exclusively. When invoking the Python command line interpreter with the -t option, it issues warnings about code that illegally mixes tabs and spaces. When using -tt these warnings become errors. These options are highly recommended! Okay: if a == 0:\n a = 1\n b = 1 E101: if a == 0:\n a = 1\n\tb = 1 """ indent = INDENT_REGEX.match(physical_line).group(1) for offset, char in enumerate(indent): if char != indent_char: return offset, "E101 indentation contains mixed spaces and tabs" @register_check def tabs_obsolete(physical_line): r"""On new projects, spaces-only are strongly recommended over tabs. Okay: if True:\n return W191: if True:\n\treturn """ indent = INDENT_REGEX.match(physical_line).group(1) if '\t' in indent: return indent.index('\t'), "W191 indentation contains tabs" @register_check def trailing_whitespace(physical_line): r"""Trailing whitespace is superfluous. The warning returned varies on whether the line itself is blank, for easier filtering for those who want to indent their blank lines. Okay: spam(1)\n# W291: spam(1) \n# W293: class Foo(object):\n \n bang = 12 """ physical_line = physical_line.rstrip('\n') # chr(10), newline physical_line = physical_line.rstrip('\r') # chr(13), carriage return physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L stripped = physical_line.rstrip(' \t\v') if physical_line != stripped: if stripped: return len(stripped), "W291 trailing whitespace" else: return 0, "W293 blank line contains whitespace" @register_check def trailing_blank_lines(physical_line, lines, line_number, total_lines): r"""Trailing blank lines are superfluous. Okay: spam(1) W391: spam(1)\n However the last line should end with a new line (warning W292). """ if line_number == total_lines: stripped_last_line = physical_line.rstrip() if physical_line and not stripped_last_line: return 0, "W391 blank line at end of file" if stripped_last_line == physical_line: return len(lines[-1]), "W292 no newline at end of file" @register_check def maximum_line_length(physical_line, max_line_length, multiline, line_number, noqa): r"""Limit all lines to a maximum of 79 characters. There are still many devices around that are limited to 80 character lines; plus, limiting windows to 80 characters makes it possible to have several windows side-by-side. The default wrapping on such devices looks ugly. Therefore, please limit all lines to a maximum of 79 characters. For flowing long blocks of text (docstrings or comments), limiting the length to 72 characters is recommended. Reports error E501. """ line = physical_line.rstrip() length = len(line) if length > max_line_length and not noqa: # Special case: ignore long shebang lines. if line_number == 1 and line.startswith('#!'): return # Special case for long URLs in multi-line docstrings or # comments, but still report the error when the 72 first chars # are whitespaces. chunks = line.split() if ((len(chunks) == 1 and multiline) or (len(chunks) == 2 and chunks[0] == '#')) and \ len(line) - len(chunks[-1]) < max_line_length - 7: return if hasattr(line, 'decode'): # Python 2 # The line could contain multi-byte characters try: length = len(line.decode('utf-8')) except UnicodeError: pass if length > max_line_length: return (max_line_length, "E501 line too long " "(%d > %d characters)" % (length, max_line_length)) ######################################################################## # Plugins (check functions) for logical lines ######################################################################## @register_check def blank_lines(logical_line, blank_lines, indent_level, line_number, blank_before, previous_logical, previous_unindented_logical_line, previous_indent_level, lines): r"""Separate top-level function and class definitions with two blank lines. Method definitions inside a class are separated by a single blank line. Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of related one-liners (e.g. a set of dummy implementations). Use blank lines in functions, sparingly, to indicate logical sections. Okay: def a():\n pass\n\n\ndef b():\n pass Okay: def a():\n pass\n\n\nasync def b():\n pass Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass Okay: default = 1\nfoo = 1 Okay: classify = 1\nfoo = 1 E301: class Foo:\n b = 0\n def bar():\n pass E302: def a():\n pass\n\ndef b(n):\n pass E302: def a():\n pass\n\nasync def b(n):\n pass E303: def a():\n pass\n\n\n\ndef b(n):\n pass E303: def a():\n\n\n\n pass E304: @decorator\n\ndef a():\n pass E305: def a():\n pass\na() E306: def a():\n def b():\n pass\n def c():\n pass """ # noqa top_level_lines = BLANK_LINES_CONFIG['top_level'] method_lines = BLANK_LINES_CONFIG['method'] if line_number < top_level_lines + 1 and not previous_logical: return # Don't expect blank lines before the first line if previous_logical.startswith('@'): if blank_lines: yield 0, "E304 blank lines found after function decorator" elif (blank_lines > top_level_lines or (indent_level and blank_lines == method_lines + 1) ): yield 0, "E303 too many blank lines (%d)" % blank_lines elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): # If this is a one-liner (i.e. the next line is not more # indented), and the previous line is also not deeper # (it would be better to check if the previous line is part # of another def/class at the same level), don't require blank # lines around this. prev_line = lines[line_number - 2] if line_number >= 2 else '' next_line = lines[line_number] if line_number < len(lines) else '' if (expand_indent(prev_line) <= indent_level and expand_indent(next_line) <= indent_level): return if indent_level: if not (blank_before == method_lines or previous_indent_level < indent_level or DOCSTRING_REGEX.match(previous_logical) ): ancestor_level = indent_level nested = False # Search backwards for a def ancestor or tree root # (top level). for line in lines[line_number - top_level_lines::-1]: if line.strip() and expand_indent(line) < ancestor_level: ancestor_level = expand_indent(line) nested = line.lstrip().startswith('def ') if nested or ancestor_level == 0: break if nested: yield 0, "E306 expected %s blank line before a " \ "nested definition, found 0" % (method_lines,) else: yield 0, "E301 expected %s blank line, found 0" % ( method_lines,) elif blank_before != top_level_lines: yield 0, "E302 expected %s blank lines, found %d" % ( top_level_lines, blank_before) elif (logical_line and not indent_level and blank_before != top_level_lines and previous_unindented_logical_line.startswith(('def ', 'class ')) ): yield 0, "E305 expected %s blank lines after " \ "class or function definition, found %d" % ( top_level_lines, blank_before) @register_check def extraneous_whitespace(logical_line): r"""Avoid extraneous whitespace. Avoid extraneous whitespace in these situations: - Immediately inside parentheses, brackets or braces. - Immediately before a comma, semicolon, or colon. Okay: spam(ham[1], {eggs: 2}) E201: spam( ham[1], {eggs: 2}) E201: spam(ham[ 1], {eggs: 2}) E201: spam(ham[1], { eggs: 2}) E202: spam(ham[1], {eggs: 2} ) E202: spam(ham[1 ], {eggs: 2}) E202: spam(ham[1], {eggs: 2 }) E203: if x == 4: print x, y; x, y = y , x E203: if x == 4: print x, y ; x, y = y, x E203: if x == 4 : print x, y; x, y = y, x """ line = logical_line for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line): text = match.group() char = text.strip() found = match.start() if text == char + ' ': # assert char in '([{' yield found + 1, "E201 whitespace after '%s'" % char elif line[found - 1] != ',': code = ('E202' if char in '}])' else 'E203') # if char in ',;:' yield found, "%s whitespace before '%s'" % (code, char) @register_check def whitespace_around_keywords(logical_line): r"""Avoid extraneous whitespace around keywords. Okay: True and False E271: True and False E272: True and False E273: True and\tFalse E274: True\tand False """ for match in KEYWORD_REGEX.finditer(logical_line): before, after = match.groups() if '\t' in before: yield match.start(1), "E274 tab before keyword" elif len(before) > 1: yield match.start(1), "E272 multiple spaces before keyword" if '\t' in after: yield match.start(2), "E273 tab after keyword" elif len(after) > 1: yield match.start(2), "E271 multiple spaces after keyword" @register_check def missing_whitespace_after_import_keyword(logical_line): r"""Multiple imports in form from x import (a, b, c) should have space between import statement and parenthesised name list. Okay: from foo import (bar, baz) E275: from foo import(bar, baz) E275: from importable.module import(bar, baz) """ line = logical_line indicator = ' import(' if line.startswith('from '): found = line.find(indicator) if -1 < found: pos = found + len(indicator) - 1 yield pos, "E275 missing whitespace after keyword" @register_check def missing_whitespace(logical_line): r"""Each comma, semicolon or colon should be followed by whitespace. Okay: [a, b] Okay: (3,) Okay: a[1:4] Okay: a[:4] Okay: a[1:] Okay: a[1:4:2] E231: ['a','b'] E231: foo(bar,baz) E231: [{'a':'b'}] """ line = logical_line for index in range(len(line) - 1): char = line[index] if char in ',;:' and line[index + 1] not in WHITESPACE: before = line[:index] if char == ':' and before.count('[') > before.count(']') and \ before.rfind('{') < before.rfind('['): continue # Slice syntax, no space required if char == ',' and line[index + 1] == ')': continue # Allow tuple with only one element: (3,) yield index, "E231 missing whitespace after '%s'" % char @register_check def indentation(logical_line, previous_logical, indent_char, indent_level, previous_indent_level): r"""Use 4 spaces per indentation level. For really old code that you don't want to mess up, you can continue to use 8-space tabs. Okay: a = 1 Okay: if a == 0:\n a = 1 E111: a = 1 E114: # a = 1 Okay: for item in items:\n pass E112: for item in items:\npass E115: for item in items:\n# Hi\n pass Okay: a = 1\nb = 2 E113: a = 1\n b = 2 E116: a = 1\n # b = 2 """ c = 0 if logical_line else 3 tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)" if indent_level % 4: yield 0, tmpl % (1 + c, "indentation is not a multiple of four") indent_expect = previous_logical.endswith(':') if indent_expect and indent_level <= previous_indent_level: yield 0, tmpl % (2 + c, "expected an indented block") elif not indent_expect and indent_level > previous_indent_level: yield 0, tmpl % (3 + c, "unexpected indentation") expected_indent_level = previous_indent_level + 4 if indent_expect and indent_level > expected_indent_level: yield 0, tmpl % (7, 'over-indented') @register_check def continued_indentation(logical_line, tokens, indent_level, hang_closing, indent_char, noqa, verbose): r"""Continuation lines indentation. Continuation lines should align wrapped elements either vertically using Python's implicit line joining inside parentheses, brackets and braces, or using a hanging indent. When using a hanging indent these considerations should be applied: - there should be no arguments on the first line, and - further indentation should be used to clearly distinguish itself as a continuation line. Okay: a = (\n) E123: a = (\n ) Okay: a = (\n 42) E121: a = (\n 42) E122: a = (\n42) E123: a = (\n 42\n ) E124: a = (24,\n 42\n) E125: if (\n b):\n pass E126: a = (\n 42) E127: a = (24,\n 42) E128: a = (24,\n 42) E129: if (a or\n b):\n pass E131: a = (\n 42\n 24) """ first_row = tokens[0][2][0] nrows = 1 + tokens[-1][2][0] - first_row if noqa or nrows == 1: return # indent_next tells us whether the next block is indented; assuming # that it is indented by 4 spaces, then we should not allow 4-space # indents on the final continuation line; in turn, some other # indents are allowed to have an extra 4 spaces. indent_next = logical_line.endswith(':') row = depth = 0 valid_hangs = (4,) if indent_char != '\t' else (4, 8) # remember how many brackets were opened on each line parens = [0] * nrows # relative indents of physical lines rel_indent = [0] * nrows # for each depth, collect a list of opening rows open_rows = [[0]] # for each depth, memorize the hanging indentation hangs = [None] # visual indents indent_chances = {} last_indent = tokens[0][2] visual_indent = None last_token_multiline = False # for each depth, memorize the visual indent column indent = [last_indent[1]] if verbose >= 3: print(">>> " + tokens[0][4].rstrip()) for token_type, text, start, end, line in tokens: newline = row < start[0] - first_row if newline: row = start[0] - first_row newline = not last_token_multiline and token_type not in NEWLINE if newline: # this is the beginning of a continuation line. last_indent = start if verbose >= 3: print("... " + line.rstrip()) # record the initial indent. rel_indent[row] = expand_indent(line) - indent_level # identify closing bracket close_bracket = (token_type == tokenize.OP and text in ']})') # is the indent relative to an opening bracket line? for open_row in reversed(open_rows[depth]): hang = rel_indent[row] - rel_indent[open_row] hanging_indent = hang in valid_hangs if hanging_indent: break if hangs[depth]: hanging_indent = (hang == hangs[depth]) # is there any chance of visual indent? visual_indent = (not close_bracket and hang > 0 and indent_chances.get(start[1])) if close_bracket and indent[depth]: # closing bracket for visual indent if start[1] != indent[depth]: yield (start, "E124 closing bracket does not match " "visual indentation") elif close_bracket and not hang: # closing bracket matches indentation of opening # bracket's line if hang_closing: yield start, "E133 closing bracket is missing indentation" elif indent[depth] and start[1] < indent[depth]: if visual_indent is not True: # visual indent is broken yield (start, "E128 continuation line " "under-indented for visual indent") elif hanging_indent or (indent_next and rel_indent[row] == 8): # hanging indent is verified if close_bracket and not hang_closing: yield (start, "E123 closing bracket does not match " "indentation of opening bracket's line") hangs[depth] = hang elif visual_indent is True: # visual indent is verified indent[depth] = start[1] elif visual_indent in (text, str): # ignore token lined up with matching one from a # previous line pass else: # indent is broken if hang <= 0: error = "E122", "missing indentation or outdented" elif indent[depth]: error = "E127", "over-indented for visual indent" elif not close_bracket and hangs[depth]: error = "E131", "unaligned for hanging indent" else: hangs[depth] = hang if hang > 4: error = "E126", "over-indented for hanging indent" else: error = "E121", "under-indented for hanging indent" yield start, "%s continuation line %s" % error # look for visual indenting if (parens[row] and token_type not in (tokenize.NL, tokenize.COMMENT) and not indent[depth]): indent[depth] = start[1] indent_chances[start[1]] = True if verbose >= 4: print("bracket depth %s indent to %s" % (depth, start[1])) # deal with implicit string concatenation elif (token_type in (tokenize.STRING, tokenize.COMMENT) or text in ('u', 'ur', 'b', 'br')): indent_chances[start[1]] = str # special case for the "if" statement because len("if (") == 4 elif not indent_chances and not row and not depth and text == 'if': indent_chances[end[1] + 1] = True elif text == ':' and line[end[1]:].isspace(): open_rows[depth].append(row) # keep track of bracket depth if token_type == tokenize.OP: if text in '([{': depth += 1 indent.append(0) hangs.append(None) if len(open_rows) == depth: open_rows.append([]) open_rows[depth].append(row) parens[row] += 1 if verbose >= 4: print("bracket depth %s seen, col %s, visual min = %s" % (depth, start[1], indent[depth])) elif text in ')]}' and depth > 0: # parent indents should not be more than this one prev_indent = indent.pop() or last_indent[1] hangs.pop() for d in range(depth): if indent[d] > prev_indent: indent[d] = 0 for ind in list(indent_chances): if ind >= prev_indent: del indent_chances[ind] del open_rows[depth + 1:] depth -= 1 if depth: indent_chances[indent[depth]] = True for idx in range(row, -1, -1): if parens[idx]: parens[idx] -= 1 break assert len(indent) == depth + 1 if start[1] not in indent_chances: # allow lining up tokens indent_chances[start[1]] = text last_token_multiline = (start[0] != end[0]) if last_token_multiline: rel_indent[end[0] - first_row] = rel_indent[row] if indent_next and expand_indent(line) == indent_level + 4: pos = (start[0], indent[0] + 4) if visual_indent: code = "E129 visually indented line" else: code = "E125 continuation line" yield pos, "%s with same indent as next logical line" % code @register_check def whitespace_before_parameters(logical_line, tokens): r"""Avoid extraneous whitespace. Avoid extraneous whitespace in the following situations: - before the open parenthesis that starts the argument list of a function call. - before the open parenthesis that starts an indexing or slicing. Okay: spam(1) E211: spam (1) Okay: dict['key'] = list[index] E211: dict ['key'] = list[index] E211: dict['key'] = list [index] """ prev_type, prev_text, __, prev_end, __ = tokens[0] for index in range(1, len(tokens)): token_type, text, start, end, __ = tokens[index] if (token_type == tokenize.OP and text in '([' and start != prev_end and (prev_type == tokenize.NAME or prev_text in '}])') and # Syntax "class A (B):" is allowed, but avoid it (index < 2 or tokens[index - 2][1] != 'class') and # Allow "return (a.foo for a in range(5))" not keyword.iskeyword(prev_text)): yield prev_end, "E211 whitespace before '%s'" % text prev_type = token_type prev_text = text prev_end = end @register_check def whitespace_around_operator(logical_line): r"""Avoid extraneous whitespace around an operator. Okay: a = 12 + 3 E221: a = 4 + 5 E222: a = 4 + 5 E223: a = 4\t+ 5 E224: a = 4 +\t5 """ for match in OPERATOR_REGEX.finditer(logical_line): before, after = match.groups() if '\t' in before: yield match.start(1), "E223 tab before operator" elif len(before) > 1: yield match.start(1), "E221 multiple spaces before operator" if '\t' in after: yield match.start(2), "E224 tab after operator" elif len(after) > 1: yield match.start(2), "E222 multiple spaces after operator" @register_check def missing_whitespace_around_operator(logical_line, tokens): r"""Surround operators with a single space on either side. - Always surround these binary operators with a single space on either side: assignment (=), augmented assignment (+=, -= etc.), comparisons (==, <, >, !=, <=, >=, in, not in, is, is not), Booleans (and, or, not). - If operators with different priorities are used, consider adding whitespace around the operators with the lowest priorities. Okay: i = i + 1 Okay: submitted += 1 Okay: x = x * 2 - 1 Okay: hypot2 = x * x + y * y Okay: c = (a + b) * (a - b) Okay: foo(bar, key='word', *args, **kwargs) Okay: alpha[:-i] E225: i=i+1 E225: submitted +=1 E225: x = x /2 - 1 E225: z = x **y E226: c = (a+b) * (a-b) E226: hypot2 = x*x + y*y E227: c = a|b E228: msg = fmt%(errno, errmsg) """ parens = 0 need_space = False prev_type = tokenize.OP prev_text = prev_end = None for token_type, text, start, end, line in tokens: if token_type in SKIP_COMMENTS: continue if text in ('(', 'lambda'): parens += 1 elif text == ')': parens -= 1 if need_space: if start != prev_end: # Found a (probably) needed space if need_space is not True and not need_space[1]: yield (need_space[0], "E225 missing whitespace around operator") need_space = False elif text == '>' and prev_text in ('<', '-'): # Tolerate the "<>" operator, even if running Python 3 # Deal with Python 3's annotated return value "->" pass else: if need_space is True or need_space[1]: # A needed trailing space was not found yield prev_end, "E225 missing whitespace around operator" elif prev_text != '**': code, optype = 'E226', 'arithmetic' if prev_text == '%': code, optype = 'E228', 'modulo' elif prev_text not in ARITHMETIC_OP: code, optype = 'E227', 'bitwise or shift' yield (need_space[0], "%s missing whitespace " "around %s operator" % (code, optype)) need_space = False elif token_type == tokenize.OP and prev_end is not None: if text == '=' and parens: # Allow keyword args or defaults: foo(bar=None). pass elif text in WS_NEEDED_OPERATORS: need_space = True elif text in UNARY_OPERATORS: # Check if the operator is used as a binary operator # Allow unary operators: -123, -x, +1. # Allow argument unpacking: foo(*args, **kwargs). if (prev_text in '}])' if prev_type == tokenize.OP else prev_text not in KEYWORDS): need_space = None elif text in WS_OPTIONAL_OPERATORS: need_space = None if need_space is None: # Surrounding space is optional, but ensure that # trailing space matches opening space need_space = (prev_end, start != prev_end) elif need_space and start == prev_end: # A needed opening space was not found yield prev_end, "E225 missing whitespace around operator" need_space = False prev_type = token_type prev_text = text prev_end = end @register_check def whitespace_around_comma(logical_line): r"""Avoid extraneous whitespace after a comma or a colon. Note: these checks are disabled by default Okay: a = (1, 2) E241: a = (1, 2) E242: a = (1,\t2) """ line = logical_line for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line): found = m.start() + 1 if '\t' in m.group(): yield found, "E242 tab after '%s'" % m.group()[0] else: yield found, "E241 multiple spaces after '%s'" % m.group()[0] @register_check def whitespace_around_named_parameter_equals(logical_line, tokens): r"""Don't use spaces around the '=' sign in function arguments. Don't use spaces around the '=' sign when used to indicate a keyword argument or a default parameter value, except when using a type annotation. Okay: def complex(real, imag=0.0): Okay: return magic(r=real, i=imag) Okay: boolean(a == b) Okay: boolean(a != b) Okay: boolean(a <= b) Okay: boolean(a >= b) Okay: def foo(arg: int = 42): Okay: async def foo(arg: int = 42): E251: def complex(real, imag = 0.0): E251: return magic(r = real, i = imag) E252: def complex(real, image: float=0.0): """ parens = 0 no_space = False require_space = False prev_end = None annotated_func_arg = False in_def = bool(STARTSWITH_DEF_REGEX.match(logical_line)) message = "E251 unexpected spaces around keyword / parameter equals" missing_message = "E252 missing whitespace around parameter equals" for token_type, text, start, end, line in tokens: if token_type == tokenize.NL: continue if no_space: no_space = False if start != prev_end: yield (prev_end, message) if require_space: require_space = False if start == prev_end: yield (prev_end, missing_message) if token_type == tokenize.OP: if text in '([': parens += 1 elif text in ')]': parens -= 1 elif in_def and text == ':' and parens == 1: annotated_func_arg = True elif parens == 1 and text == ',': annotated_func_arg = False elif parens and text == '=': if annotated_func_arg and parens == 1: require_space = True if start == prev_end: yield (prev_end, missing_message) else: no_space = True if start != prev_end: yield (prev_end, message) if not parens: annotated_func_arg = False prev_end = end @register_check def whitespace_before_comment(logical_line, tokens): r"""Separate inline comments by at least two spaces. An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. They should start with a # and a single space. Each line of a block comment starts with a # and a single space (unless it is indented text inside the comment). Okay: x = x + 1 # Increment x Okay: x = x + 1 # Increment x Okay: # Block comment E261: x = x + 1 # Increment x E262: x = x + 1 #Increment x E262: x = x + 1 # Increment x E265: #Block comment E266: ### Block comment """ prev_end = (0, 0) for token_type, text, start, end, line in tokens: if token_type == tokenize.COMMENT: inline_comment = line[:start[1]].strip() if inline_comment: if prev_end[0] == start[0] and start[1] < prev_end[1] + 2: yield (prev_end, "E261 at least two spaces before inline comment") symbol, sp, comment = text.partition(' ') bad_prefix = symbol not in '#:' and (symbol.lstrip('#')[:1] or '#') if inline_comment: if bad_prefix or comment[:1] in WHITESPACE: yield start, "E262 inline comment should start with '# '" elif bad_prefix and (bad_prefix != '!' or start[0] > 1): if bad_prefix != '#': yield start, "E265 block comment should start with '# '" elif comment: yield start, "E266 too many leading '#' for block comment" elif token_type != tokenize.NL: prev_end = end @register_check def imports_on_separate_lines(logical_line): r"""Place imports on separate lines. Okay: import os\nimport sys E401: import sys, os Okay: from subprocess import Popen, PIPE Okay: from myclas import MyClass Okay: from foo.bar.yourclass import YourClass Okay: import myclass Okay: import foo.bar.yourclass """ line = logical_line if line.startswith('import '): found = line.find(',') if -1 < found and ';' not in line[:found]: yield found, "E401 multiple imports on one line" @register_check def module_imports_on_top_of_file( logical_line, indent_level, checker_state, noqa): r"""Place imports at the top of the file. Always put imports at the top of the file, just after any module comments and docstrings, and before module globals and constants. Okay: import os Okay: # this is a comment\nimport os Okay: '''this is a module docstring'''\nimport os Okay: r'''this is a module docstring'''\nimport os Okay: try:\n\timport x\nexcept ImportError:\n\tpass\nelse:\n\tpass\nimport y Okay: try:\n\timport x\nexcept ImportError:\n\tpass\nfinally:\n\tpass\nimport y E402: a=1\nimport os E402: 'One string'\n"Two string"\nimport os E402: a=1\nfrom sys import x Okay: if x:\n import os """ # noqa def is_string_literal(line): if line[0] in 'uUbB': line = line[1:] if line and line[0] in 'rR': line = line[1:] return line and (line[0] == '"' or line[0] == "'") allowed_try_keywords = ('try', 'except', 'else', 'finally') if indent_level: # Allow imports in conditional statement/function return if not logical_line: # Allow empty lines or comments return if noqa: return line = logical_line if line.startswith('import ') or line.startswith('from '): if checker_state.get('seen_non_imports', False): yield 0, "E402 module level import not at top of file" elif re.match(DUNDER_REGEX, line): return elif any(line.startswith(kw) for kw in allowed_try_keywords): # Allow try, except, else, finally keywords intermixed with # imports in order to support conditional importing return elif is_string_literal(line): # The first literal is a docstring, allow it. Otherwise, report # error. if checker_state.get('seen_docstring', False): checker_state['seen_non_imports'] = True else: checker_state['seen_docstring'] = True else: checker_state['seen_non_imports'] = True @register_check def compound_statements(logical_line): r"""Compound statements (on the same line) are generally discouraged. While sometimes it's okay to put an if/for/while with a small body on the same line, never do this for multi-clause statements. Also avoid folding such long lines! Always use a def statement instead of an assignment statement that binds a lambda expression directly to a name. Okay: if foo == 'blah':\n do_blah_thing() Okay: do_one() Okay: do_two() Okay: do_three() E701: if foo == 'blah': do_blah_thing() E701: for x in lst: total += x E701: while t < 10: t = delay() E701: if foo == 'blah': do_blah_thing() E701: else: do_non_blah_thing() E701: try: something() E701: finally: cleanup() E701: if foo == 'blah': one(); two(); three() E702: do_one(); do_two(); do_three() E703: do_four(); # useless semicolon E704: def f(x): return 2*x E731: f = lambda x: 2*x """ line = logical_line last_char = len(line) - 1 found = line.find(':') prev_found = 0 counts = {char: 0 for char in '{}[]()'} while -1 < found < last_char: update_counts(line[prev_found:found], counts) if ((counts['{'] <= counts['}'] and # {'a': 1} (dict) counts['['] <= counts[']'] and # [1:2] (slice) counts['('] <= counts[')'])): # (annotation) lambda_kw = LAMBDA_REGEX.search(line, 0, found) if lambda_kw: before = line[:lambda_kw.start()].rstrip() if before[-1:] == '=' and isidentifier(before[:-1].strip()): yield 0, ("E731 do not assign a lambda expression, use a " "def") break if STARTSWITH_DEF_REGEX.match(line): yield 0, "E704 multiple statements on one line (def)" elif STARTSWITH_INDENT_STATEMENT_REGEX.match(line): yield found, "E701 multiple statements on one line (colon)" prev_found = found found = line.find(':', found + 1) found = line.find(';') while -1 < found: if found < last_char: yield found, "E702 multiple statements on one line (semicolon)" else: yield found, "E703 statement ends with a semicolon" found = line.find(';', found + 1) @register_check def explicit_line_join(logical_line, tokens): r"""Avoid explicit line join between brackets. The preferred way of wrapping long lines is by using Python's implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation. E502: aaa = [123, \\n 123] E502: aaa = ("bbb " \\n "ccc") Okay: aaa = [123,\n 123] Okay: aaa = ("bbb "\n "ccc") Okay: aaa = "bbb " \\n "ccc" Okay: aaa = 123 # \\ """ prev_start = prev_end = parens = 0 comment = False backslash = None for token_type, text, start, end, line in tokens: if token_type == tokenize.COMMENT: comment = True if start[0] != prev_start and parens and backslash and not comment: yield backslash, "E502 the backslash is redundant between brackets" if end[0] != prev_end: if line.rstrip('\r\n').endswith('\\'): backslash = (end[0], len(line.splitlines()[-1]) - 1) else: backslash = None prev_start = prev_end = end[0] else: prev_start = start[0] if token_type == tokenize.OP: if text in '([{': parens += 1 elif text in ')]}': parens -= 1 def _is_binary_operator(token_type, text): is_op_token = token_type == tokenize.OP is_conjunction = text in ['and', 'or'] # NOTE(sigmavirus24): Previously the not_a_symbol check was executed # conditionally. Since it is now *always* executed, text may be # None. In that case we get a TypeError for `text not in str`. not_a_symbol = text and text not in "()[]{},:.;@=%~" # The % character is strictly speaking a binary operator, but the # common usage seems to be to put it next to the format parameters, # after a line break. return ((is_op_token or is_conjunction) and not_a_symbol) def _break_around_binary_operators(tokens): """Private function to reduce duplication. This factors out the shared details between :func:`break_before_binary_operator` and :func:`break_after_binary_operator`. """ line_break = False unary_context = True # Previous non-newline token types and text previous_token_type = None previous_text = None for token_type, text, start, end, line in tokens: if token_type == tokenize.COMMENT: continue if ('\n' in text or '\r' in text) and token_type != tokenize.STRING: line_break = True else: yield (token_type, text, previous_token_type, previous_text, line_break, unary_context, start) unary_context = text in '([{,;' line_break = False previous_token_type = token_type previous_text = text @register_check def break_before_binary_operator(logical_line, tokens): r""" Avoid breaks before binary operators. The preferred place to break around a binary operator is after the operator, not before it. W503: (width == 0\n + height == 0) W503: (width == 0\n and height == 0) W503: var = (1\n & ~2) W503: var = (1\n / -2) W503: var = (1\n + -1\n + -2) Okay: foo(\n -x) Okay: foo(x\n []) Okay: x = '''\n''' + '' Okay: foo(x,\n -y) Okay: foo(x, # comment\n -y) """ for context in _break_around_binary_operators(tokens): (token_type, text, previous_token_type, previous_text, line_break, unary_context, start) = context if (_is_binary_operator(token_type, text) and line_break and not unary_context and not _is_binary_operator(previous_token_type, previous_text)): yield start, "W503 line break before binary operator" @register_check def break_after_binary_operator(logical_line, tokens): r""" Avoid breaks after binary operators. The preferred place to break around a binary operator is before the operator, not after it. W504: (width == 0 +\n height == 0) W504: (width == 0 and\n height == 0) W504: var = (1 &\n ~2) Okay: foo(\n -x) Okay: foo(x\n []) Okay: x = '''\n''' + '' Okay: x = '' + '''\n''' Okay: foo(x,\n -y) Okay: foo(x, # comment\n -y) The following should be W504 but unary_context is tricky with these Okay: var = (1 /\n -2) Okay: var = (1 +\n -1 +\n -2) """ prev_start = None for context in _break_around_binary_operators(tokens): (token_type, text, previous_token_type, previous_text, line_break, unary_context, start) = context if (_is_binary_operator(previous_token_type, previous_text) and line_break and not unary_context and not _is_binary_operator(token_type, text)): yield prev_start, "W504 line break after binary operator" prev_start = start @register_check def comparison_to_singleton(logical_line, noqa): r"""Comparison to singletons should use "is" or "is not". Comparisons to singletons like None should always be done with "is" or "is not", never the equality operators. Okay: if arg is not None: E711: if arg != None: E711: if None == arg: E712: if arg == True: E712: if False == arg: Also, beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context! """ match = not noqa and COMPARE_SINGLETON_REGEX.search(logical_line) if match: singleton = match.group(1) or match.group(3) same = (match.group(2) == '==') msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton) if singleton in ('None',): code = 'E711' else: code = 'E712' nonzero = ((singleton == 'True' and same) or (singleton == 'False' and not same)) msg += " or 'if %scond:'" % ('' if nonzero else 'not ') yield match.start(2), ("%s comparison to %s should be %s" % (code, singleton, msg)) @register_check def comparison_negative(logical_line): r"""Negative comparison should be done using "not in" and "is not". Okay: if x not in y:\n pass Okay: assert (X in Y or X is Z) Okay: if not (X in Y):\n pass Okay: zz = x is not y E713: Z = not X in Y E713: if not X.B in Y:\n pass E714: if not X is Y:\n pass E714: Z = not X.B is Y """ match = COMPARE_NEGATIVE_REGEX.search(logical_line) if match: pos = match.start(1) if match.group(2) == 'in': yield pos, "E713 test for membership should be 'not in'" else: yield pos, "E714 test for object identity should be 'is not'" @register_check def comparison_type(logical_line, noqa): r"""Object type comparisons should always use isinstance(). Do not compare types directly. Okay: if isinstance(obj, int): E721: if type(obj) is type(1): When checking if an object is a string, keep in mind that it might be a unicode string too! In Python 2.3, str and unicode have a common base class, basestring, so you can do: Okay: if isinstance(obj, basestring): Okay: if type(a1) is type(b1): """ match = COMPARE_TYPE_REGEX.search(logical_line) if match and not noqa: inst = match.group(1) if inst and isidentifier(inst) and inst not in SINGLETONS: return # Allow comparison for types which are not obvious yield match.start(), "E721 do not compare types, use 'isinstance()'" @register_check def bare_except(logical_line, noqa): r"""When catching exceptions, mention specific exceptions when possible. Okay: except Exception: Okay: except BaseException: E722: except: """ if noqa: return regex = re.compile(r"except\s*:") match = regex.match(logical_line) if match: yield match.start(), "E722 do not use bare 'except'" @register_check def ambiguous_identifier(logical_line, tokens): r"""Never use the characters 'l', 'O', or 'I' as variable names. In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use 'l', use 'L' instead. Okay: L = 0 Okay: o = 123 Okay: i = 42 E741: l = 0 E741: O = 123 E741: I = 42 Variables can be bound in several other contexts, including class and function definitions, 'global' and 'nonlocal' statements, exception handlers, and 'with' statements. Okay: except AttributeError as o: Okay: with lock as L: E741: except AttributeError as O: E741: with lock as l: E741: global I E741: nonlocal l E742: class I(object): E743: def l(x): """ idents_to_avoid = ('l', 'O', 'I') prev_type, prev_text, prev_start, prev_end, __ = tokens[0] for token_type, text, start, end, line in tokens[1:]: ident = pos = None # identifiers on the lhs of an assignment operator if token_type == tokenize.OP and '=' in text: if prev_text in idents_to_avoid: ident = prev_text pos = prev_start # identifiers bound to values with 'as', 'global', or 'nonlocal' if prev_text in ('as', 'global', 'nonlocal'): if text in idents_to_avoid: ident = text pos = start if prev_text == 'class': if text in idents_to_avoid: yield start, "E742 ambiguous class definition '%s'" % text if prev_text == 'def': if text in idents_to_avoid: yield start, "E743 ambiguous function definition '%s'" % text if ident: yield pos, "E741 ambiguous variable name '%s'" % ident prev_text = text prev_start = start @register_check def python_3000_has_key(logical_line, noqa): r"""The {}.has_key() method is removed in Python 3: use the 'in' operator. Okay: if "alph" in d:\n print d["alph"] W601: assert d.has_key('alph') """ pos = logical_line.find('.has_key(') if pos > -1 and not noqa: yield pos, "W601 .has_key() is deprecated, use 'in'" @register_check def python_3000_raise_comma(logical_line): r"""When raising an exception, use "raise ValueError('message')". The older form is removed in Python 3. Okay: raise DummyError("Message") W602: raise DummyError, "Message" """ match = RAISE_COMMA_REGEX.match(logical_line) if match and not RERAISE_COMMA_REGEX.match(logical_line): yield match.end() - 1, "W602 deprecated form of raising exception" @register_check def python_3000_not_equal(logical_line): r"""New code should always use != instead of <>. The older syntax is removed in Python 3. Okay: if a != 'no': W603: if a <> 'no': """ pos = logical_line.find('<>') if pos > -1: yield pos, "W603 '<>' is deprecated, use '!='" @register_check def python_3000_backticks(logical_line): r"""Use repr() instead of backticks in Python 3. Okay: val = repr(1 + 2) W604: val = `1 + 2` """ pos = logical_line.find('`') if pos > -1: yield pos, "W604 backticks are deprecated, use 'repr()'" @register_check def python_3000_invalid_escape_sequence(logical_line, tokens, noqa): r"""Invalid escape sequences are deprecated in Python 3.6. Okay: regex = r'\.png$' W605: regex = '\.png$' """ if noqa: return # https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals valid = [ '\n', '\\', '\'', '"', 'a', 'b', 'f', 'n', 'r', 't', 'v', '0', '1', '2', '3', '4', '5', '6', '7', 'x', # Escape sequences only recognized in string literals 'N', 'u', 'U', ] for token_type, text, start, end, line in tokens: if token_type == tokenize.STRING: start_line, start_col = start quote = text[-3:] if text[-3:] in ('"""', "'''") else text[-1] # Extract string modifiers (e.g. u or r) quote_pos = text.index(quote) prefix = text[:quote_pos].lower() start = quote_pos + len(quote) string = text[start:-len(quote)] if 'r' not in prefix: pos = string.find('\\') while pos >= 0: pos += 1 if string[pos] not in valid: line = start_line + string.count('\n', 0, pos) if line == start_line: col = start_col + len(prefix) + len(quote) + pos else: col = pos - string.rfind('\n', 0, pos) - 1 yield ( (line, col - 1), "W605 invalid escape sequence '\\%s'" % string[pos], ) pos = string.find('\\', pos + 1) @register_check def python_3000_async_await_keywords(logical_line, tokens): """'async' and 'await' are reserved keywords starting at Python 3.7. W606: async = 42 W606: await = 42 Okay: async def read(db):\n data = await db.fetch('SELECT ...') """ # The Python tokenize library before Python 3.5 recognizes # async/await as a NAME token. Therefore, use a state machine to # look for the possible async/await constructs as defined by the # Python grammar: # https://docs.python.org/3/reference/grammar.html state = None for token_type, text, start, end, line in tokens: error = False if token_type == tokenize.NL: continue if state is None: if token_type == tokenize.NAME: if text == 'async': state = ('async_stmt', start) elif text == 'await': state = ('await', start) elif (token_type == tokenize.NAME and text in ('def', 'for')): state = ('define', start) elif state[0] == 'async_stmt': if token_type == tokenize.NAME and text in ('def', 'with', 'for'): # One of funcdef, with_stmt, or for_stmt. Return to # looking for async/await names. state = None else: error = True elif state[0] == 'await': if token_type == tokenize.NAME: # An await expression. Return to looking for async/await # names. state = None elif token_type == tokenize.OP and text == '(': state = None else: error = True elif state[0] == 'define': if token_type == tokenize.NAME and text in ('async', 'await'): error = True else: state = None if error: yield ( state[1], "W606 'async' and 'await' are reserved keywords starting with " "Python 3.7", ) state = None # Last token if state is not None: yield ( state[1], "W606 'async' and 'await' are reserved keywords starting with " "Python 3.7", ) ######################################################################## @register_check def maximum_doc_length(logical_line, max_doc_length, noqa, tokens): r"""Limit all doc lines to a maximum of 72 characters. For flowing long blocks of text (docstrings or comments), limiting the length to 72 characters is recommended. Reports warning W505 """ if max_doc_length is None or noqa: return prev_token = None skip_lines = set() # Skip lines that for token_type, text, start, end, line in tokens: if token_type not in SKIP_COMMENTS.union([tokenize.STRING]): skip_lines.add(line) for token_type, text, start, end, line in tokens: # Skip lines that aren't pure strings if token_type == tokenize.STRING and skip_lines: continue if token_type in (tokenize.STRING, tokenize.COMMENT): # Only check comment-only lines if prev_token is None or prev_token in SKIP_TOKENS: lines = line.splitlines() for line_num, physical_line in enumerate(lines): if hasattr(physical_line, 'decode'): # Python 2 # The line could contain multi-byte characters try: physical_line = physical_line.decode('utf-8') except UnicodeError: pass if start[0] + line_num == 1 and line.startswith('#!'): return length = len(physical_line) chunks = physical_line.split() if token_type == tokenize.COMMENT: if (len(chunks) == 2 and length - len(chunks[-1]) < MAX_DOC_LENGTH): continue if len(chunks) == 1 and line_num + 1 < len(lines): if (len(chunks) == 1 and length - len(chunks[-1]) < MAX_DOC_LENGTH): continue if length > max_doc_length: doc_error = (start[0] + line_num, max_doc_length) yield (doc_error, "W505 doc line too long " "(%d > %d characters)" % (length, max_doc_length)) prev_token = token_type ######################################################################## # Helper functions ######################################################################## if sys.version_info < (3,): # Python 2: implicit encoding. def readlines(filename): """Read the source code.""" with open(filename, 'rU') as f: return f.readlines() isidentifier = re.compile(r'[a-zA-Z_]\w*$').match stdin_get_value = sys.stdin.read else: # Python 3 def readlines(filename): """Read the source code.""" try: with open(filename, 'rb') as f: (coding, lines) = tokenize.detect_encoding(f.readline) f = TextIOWrapper(f, coding, line_buffering=True) return [line.decode(coding) for line in lines] + f.readlines() except (LookupError, SyntaxError, UnicodeError): # Fall back if file encoding is improperly declared with open(filename, encoding='latin-1') as f: return f.readlines() isidentifier = str.isidentifier def stdin_get_value(): """Read the value from stdin.""" return TextIOWrapper(sys.stdin.buffer, errors='ignore').read() noqa = lru_cache(512)(re.compile(r'# no(?:qa|pep8)\b', re.I).search) def expand_indent(line): r"""Return the amount of indentation. Tabs are expanded to the next multiple of 8. >>> expand_indent(' ') 4 >>> expand_indent('\t') 8 >>> expand_indent(' \t') 8 >>> expand_indent(' \t') 16 """ if '\t' not in line: return len(line) - len(line.lstrip()) result = 0 for char in line: if char == '\t': result = result // 8 * 8 + 8 elif char == ' ': result += 1 else: break return result def mute_string(text): """Replace contents with 'xxx' to prevent syntax matching. >>> mute_string('"abc"') '"xxx"' >>> mute_string("'''abc'''") "'''xxx'''" >>> mute_string("r'abc'") "r'xxx'" """ # String modifiers (e.g. u or r) start = text.index(text[-1]) + 1 end = len(text) - 1 # Triple quotes if text[-3:] in ('"""', "'''"): start += 2 end -= 2 return text[:start] + 'x' * (end - start) + text[end:] def parse_udiff(diff, patterns=None, parent='.'): """Return a dictionary of matching lines.""" # For each file of the diff, the entry key is the filename, # and the value is a set of row numbers to consider. rv = {} path = nrows = None for line in diff.splitlines(): if nrows: if line[:1] != '-': nrows -= 1 continue if line[:3] == '@@ ': hunk_match = HUNK_REGEX.match(line) (row, nrows) = [int(g or '1') for g in hunk_match.groups()] rv[path].update(range(row, row + nrows)) elif line[:3] == '+++': path = line[4:].split('\t', 1)[0] # Git diff will use (i)ndex, (w)ork tree, (c)ommit and # (o)bject instead of a/b/c/d as prefixes for patches if path[:2] in ('b/', 'w/', 'i/'): path = path[2:] rv[path] = set() return { os.path.join(parent, filepath): rows for (filepath, rows) in rv.items() if rows and filename_match(filepath, patterns) } def normalize_paths(value, parent=os.curdir): """Parse a comma-separated list of paths. Return a list of absolute paths. """ if not value: return [] if isinstance(value, list): return value paths = [] for path in value.split(','): path = path.strip() if '/' in path: path = os.path.abspath(os.path.join(parent, path)) paths.append(path.rstrip('/')) return paths def filename_match(filename, patterns, default=True): """Check if patterns contains a pattern that matches filename. If patterns is unspecified, this always returns True. """ if not patterns: return default return any(fnmatch(filename, pattern) for pattern in patterns) def update_counts(s, counts): r"""Adds one to the counts of each appearance of characters in s, for characters in counts""" for char in s: if char in counts: counts[char] += 1 def _is_eol_token(token): return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n' ######################################################################## # Framework to run all checks ######################################################################## class Checker(object): """Load a Python source file, tokenize it, check coding style.""" def __init__(self, filename=None, lines=None, options=None, report=None, **kwargs): if options is None: options = StyleGuide(kwargs).options else: assert not kwargs self._io_error = None self._physical_checks = options.physical_checks self._logical_checks = options.logical_checks self._ast_checks = options.ast_checks self.max_line_length = options.max_line_length self.max_doc_length = options.max_doc_length self.multiline = False # in a multiline string? self.hang_closing = options.hang_closing self.verbose = options.verbose self.filename = filename # Dictionary where a checker can store its custom state. self._checker_states = {} if filename is None: self.filename = 'stdin' self.lines = lines or [] elif filename == '-': self.filename = 'stdin' self.lines = stdin_get_value().splitlines(True) elif lines is None: try: self.lines = readlines(filename) except IOError: (exc_type, exc) = sys.exc_info()[:2] self._io_error = '%s: %s' % (exc_type.__name__, exc) self.lines = [] else: self.lines = lines if self.lines: ord0 = ord(self.lines[0][0]) if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM if ord0 == 0xfeff: self.lines[0] = self.lines[0][1:] elif self.lines[0][:3] == '\xef\xbb\xbf': self.lines[0] = self.lines[0][3:] self.report = report or options.report self.report_error = self.report.error self.noqa = False def report_invalid_syntax(self): """Check if the syntax is valid.""" (exc_type, exc) = sys.exc_info()[:2] if len(exc.args) > 1: offset = exc.args[1] if len(offset) > 2: offset = offset[1:3] else: offset = (1, 0) self.report_error(offset[0], offset[1] or 0, 'E901 %s: %s' % (exc_type.__name__, exc.args[0]), self.report_invalid_syntax) def readline(self): """Get the next line from the input buffer.""" if self.line_number >= self.total_lines: return '' line = self.lines[self.line_number] self.line_number += 1 if self.indent_char is None and line[:1] in WHITESPACE: self.indent_char = line[0] return line def run_check(self, check, argument_names): """Run a check plugin.""" arguments = [] for name in argument_names: arguments.append(getattr(self, name)) return check(*arguments) def init_checker_state(self, name, argument_names): """Prepare custom state for the specific checker plugin.""" if 'checker_state' in argument_names: self.checker_state = self._checker_states.setdefault(name, {}) def check_physical(self, line): """Run all physical checks on a raw input line.""" self.physical_line = line for name, check, argument_names in self._physical_checks: self.init_checker_state(name, argument_names) result = self.run_check(check, argument_names) if result is not None: (offset, text) = result self.report_error(self.line_number, offset, text, check) if text[:4] == 'E101': self.indent_char = line[0] def build_tokens_line(self): """Build a logical line from tokens.""" logical = [] comments = [] length = 0 prev_row = prev_col = mapping = None for token_type, text, start, end, line in self.tokens: if token_type in SKIP_TOKENS: continue if not mapping: mapping = [(0, start)] if token_type == tokenize.COMMENT: comments.append(text) continue if token_type == tokenize.STRING: text = mute_string(text) if prev_row: (start_row, start_col) = start if prev_row != start_row: # different row prev_text = self.lines[prev_row - 1][prev_col - 1] if prev_text == ',' or (prev_text not in '{[(' and text not in '}])'): text = ' ' + text elif prev_col != start_col: # different column text = line[prev_col:start_col] + text logical.append(text) length += len(text) mapping.append((length, end)) (prev_row, prev_col) = end self.logical_line = ''.join(logical) self.noqa = comments and noqa(''.join(comments)) return mapping def check_logical(self): """Build a line from tokens and run all logical checks on it.""" self.report.increment_logical_line() mapping = self.build_tokens_line() if not mapping: return mapping_offsets = [offset for offset, _ in mapping] (start_row, start_col) = mapping[0][1] start_line = self.lines[start_row - 1] self.indent_level = expand_indent(start_line[:start_col]) if self.blank_before < self.blank_lines: self.blank_before = self.blank_lines if self.verbose >= 2: print(self.logical_line[:80].rstrip()) for name, check, argument_names in self._logical_checks: if self.verbose >= 4: print(' ' + name) self.init_checker_state(name, argument_names) for offset, text in self.run_check(check, argument_names) or (): if not isinstance(offset, tuple): # As mappings are ordered, bisecting is a fast way # to find a given offset in them. token_offset, pos = mapping[bisect.bisect_left( mapping_offsets, offset)] offset = (pos[0], pos[1] + offset - token_offset) self.report_error(offset[0], offset[1], text, check) if self.logical_line: self.previous_indent_level = self.indent_level self.previous_logical = self.logical_line if not self.indent_level: self.previous_unindented_logical_line = self.logical_line self.blank_lines = 0 self.tokens = [] def check_ast(self): """Build the file's AST and run all AST checks.""" try: tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST) except (ValueError, SyntaxError, TypeError): return self.report_invalid_syntax() for name, cls, __ in self._ast_checks: checker = cls(tree, self.filename) for lineno, offset, text, check in checker.run(): if not self.lines or not noqa(self.lines[lineno - 1]): self.report_error(lineno, offset, text, check) def generate_tokens(self): """Tokenize file, run physical line checks and yield tokens.""" if self._io_error: self.report_error(1, 0, 'E902 %s' % self._io_error, readlines) tokengen = tokenize.generate_tokens(self.readline) try: for token in tokengen: if token[2][0] > self.total_lines: return self.noqa = token[4] and noqa(token[4]) self.maybe_check_physical(token) yield token except (SyntaxError, tokenize.TokenError): self.report_invalid_syntax() def maybe_check_physical(self, token): """If appropriate for token, check current physical line(s).""" # Called after every token, but act only on end of line. if _is_eol_token(token): # Obviously, a newline token ends a single physical line. self.check_physical(token[4]) elif token[0] == tokenize.STRING and '\n' in token[1]: # Less obviously, a string that contains newlines is a # multiline string, either triple-quoted or with internal # newlines backslash-escaped. Check every physical line in # the string *except* for the last one: its newline is # outside of the multiline string, so we consider it a # regular physical line, and will check it like any other # physical line. # # Subtleties: # - we don't *completely* ignore the last line; if it # contains the magical "# noqa" comment, we disable all # physical checks for the entire multiline string # - have to wind self.line_number back because initially it # points to the last line of the string, and we want # check_physical() to give accurate feedback if noqa(token[4]): return self.multiline = True self.line_number = token[2][0] _, src, (_, offset), _, _ = token src = self.lines[self.line_number - 1][:offset] + src for line in src.split('\n')[:-1]: self.check_physical(line + '\n') self.line_number += 1 self.multiline = False def check_all(self, expected=None, line_offset=0): """Run all checks on the input file.""" self.report.init_file(self.filename, self.lines, expected, line_offset) self.total_lines = len(self.lines) if self._ast_checks: self.check_ast() self.line_number = 0 self.indent_char = None self.indent_level = self.previous_indent_level = 0 self.previous_logical = '' self.previous_unindented_logical_line = '' self.tokens = [] self.blank_lines = self.blank_before = 0 parens = 0 for token in self.generate_tokens(): self.tokens.append(token) token_type, text = token[0:2] if self.verbose >= 3: if token[2][0] == token[3][0]: pos = '[%s:%s]' % (token[2][1] or '', token[3][1]) else: pos = 'l.%s' % token[3][0] print('l.%s\t%s\t%s\t%r' % (token[2][0], pos, tokenize.tok_name[token[0]], text)) if token_type == tokenize.OP: if text in '([{': parens += 1 elif text in '}])': parens -= 1 elif not parens: if token_type in NEWLINE: if token_type == tokenize.NEWLINE: self.check_logical() self.blank_before = 0 elif len(self.tokens) == 1: # The physical line contains only this token. self.blank_lines += 1 del self.tokens[0] else: self.check_logical() if self.tokens: self.check_physical(self.lines[-1]) self.check_logical() return self.report.get_file_results() class BaseReport(object): """Collect the results of the checks.""" print_filename = False def __init__(self, options): self._benchmark_keys = options.benchmark_keys self._ignore_code = options.ignore_code # Results self.elapsed = 0 self.total_errors = 0 self.counters = dict.fromkeys(self._benchmark_keys, 0) self.messages = {} def start(self): """Start the timer.""" self._start_time = time.time() def stop(self): """Stop the timer.""" self.elapsed = time.time() - self._start_time def init_file(self, filename, lines, expected, line_offset): """Signal a new file.""" self.filename = filename self.lines = lines self.expected = expected or () self.line_offset = line_offset self.file_errors = 0 self.counters['files'] += 1 self.counters['physical lines'] += len(lines) def increment_logical_line(self): """Signal a new logical line.""" self.counters['logical lines'] += 1 def error(self, line_number, offset, text, check): """Report an error, according to options.""" code = text[:4] if self._ignore_code(code): return if code in self.counters: self.counters[code] += 1 else: self.counters[code] = 1 self.messages[code] = text[5:] # Don't care about expected errors or warnings if code in self.expected: return if self.print_filename and not self.file_errors: print(self.filename) self.file_errors += 1 self.total_errors += 1 return code def get_file_results(self): """Return the count of errors and warnings for this file.""" return self.file_errors def get_count(self, prefix=''): """Return the total count of errors and warnings.""" return sum(self.counters[key] for key in self.messages if key.startswith(prefix)) def get_statistics(self, prefix=''): """Get statistics for message codes that start with the prefix. prefix='' matches all errors and warnings prefix='E' matches all errors prefix='W' matches all warnings prefix='E4' matches all errors that have to do with imports """ return ['%-7s %s %s' % (self.counters[key], key, self.messages[key]) for key in sorted(self.messages) if key.startswith(prefix)] def print_statistics(self, prefix=''): """Print overall statistics (number of errors and warnings).""" for line in self.get_statistics(prefix): print(line) def print_benchmark(self): """Print benchmark numbers.""" print('%-7.2f %s' % (self.elapsed, 'seconds elapsed')) if self.elapsed: for key in self._benchmark_keys: print('%-7d %s per second (%d total)' % (self.counters[key] / self.elapsed, key, self.counters[key])) class FileReport(BaseReport): """Collect the results of the checks and print the filenames.""" print_filename = True class StandardReport(BaseReport): """Collect and print the results of the checks.""" def __init__(self, options): super(StandardReport, self).__init__(options) self._fmt = REPORT_FORMAT.get(options.format.lower(), options.format) self._repeat = options.repeat self._show_source = options.show_source self._show_pep8 = options.show_pep8 def init_file(self, filename, lines, expected, line_offset): """Signal a new file.""" self._deferred_print = [] return super(StandardReport, self).init_file( filename, lines, expected, line_offset) def error(self, line_number, offset, text, check): """Report an error, according to options.""" code = super(StandardReport, self).error(line_number, offset, text, check) if code and (self.counters[code] == 1 or self._repeat): self._deferred_print.append( (line_number, offset, code, text[5:], check.__doc__)) return code def get_file_results(self): """Print results and return the overall count for this file.""" self._deferred_print.sort() for line_number, offset, code, text, doc in self._deferred_print: print(self._fmt % { 'path': self.filename, 'row': self.line_offset + line_number, 'col': offset + 1, 'code': code, 'text': text, }) if self._show_source: if line_number > len(self.lines): line = '' else: line = self.lines[line_number - 1] print(line.rstrip()) print(re.sub(r'\S', ' ', line[:offset]) + '^') if self._show_pep8 and doc: print(' ' + doc.strip()) # stdout is block buffered when not stdout.isatty(). # line can be broken where buffer boundary since other # processes write to same file. # flush() after print() to avoid buffer boundary. # Typical buffer size is 8192. line written safely when # len(line) < 8192. sys.stdout.flush() return self.file_errors class DiffReport(StandardReport): """Collect and print the results for the changed lines only.""" def __init__(self, options): super(DiffReport, self).__init__(options) self._selected = options.selected_lines def error(self, line_number, offset, text, check): if line_number not in self._selected[self.filename]: return return super(DiffReport, self).error(line_number, offset, text, check) class StyleGuide(object): """Initialize a PEP-8 instance with few options.""" def __init__(self, *args, **kwargs): # build options from the command line self.checker_class = kwargs.pop('checker_class', Checker) parse_argv = kwargs.pop('parse_argv', False) config_file = kwargs.pop('config_file', False) parser = kwargs.pop('parser', None) # build options from dict options_dict = dict(*args, **kwargs) arglist = None if parse_argv else options_dict.get('paths', None) verbose = options_dict.get('verbose', None) options, self.paths = process_options( arglist, parse_argv, config_file, parser, verbose) if options_dict: options.__dict__.update(options_dict) if 'paths' in options_dict: self.paths = options_dict['paths'] self.runner = self.input_file self.options = options if not options.reporter: options.reporter = BaseReport if options.quiet else StandardReport options.select = tuple(options.select or ()) if not (options.select or options.ignore or options.testsuite or options.doctest) and DEFAULT_IGNORE: # The default choice: ignore controversial checks options.ignore = tuple(DEFAULT_IGNORE.split(',')) else: # Ignore all checks which are not explicitly selected options.ignore = ('',) if options.select else tuple(options.ignore) options.benchmark_keys = BENCHMARK_KEYS[:] options.ignore_code = self.ignore_code options.physical_checks = self.get_checks('physical_line') options.logical_checks = self.get_checks('logical_line') options.ast_checks = self.get_checks('tree') self.init_report() def init_report(self, reporter=None): """Initialize the report instance.""" self.options.report = (reporter or self.options.reporter)(self.options) return self.options.report def check_files(self, paths=None): """Run all checks on the paths.""" if paths is None: paths = self.paths report = self.options.report runner = self.runner report.start() try: for path in paths: if os.path.isdir(path): self.input_dir(path) elif not self.excluded(path): runner(path) except KeyboardInterrupt: print('... stopped') report.stop() return report def input_file(self, filename, lines=None, expected=None, line_offset=0): """Run all checks on a Python source file.""" if self.options.verbose: print('checking %s' % filename) fchecker = self.checker_class( filename, lines=lines, options=self.options) return fchecker.check_all(expected=expected, line_offset=line_offset) def input_dir(self, dirname): """Check all files in this directory and all subdirectories.""" dirname = dirname.rstrip('/') if self.excluded(dirname): return 0 counters = self.options.report.counters verbose = self.options.verbose filepatterns = self.options.filename runner = self.runner for root, dirs, files in os.walk(dirname): if verbose: print('directory ' + root) counters['directories'] += 1 for subdir in sorted(dirs): if self.excluded(subdir, root): dirs.remove(subdir) for filename in sorted(files): # contain a pattern that matches? if ((filename_match(filename, filepatterns) and not self.excluded(filename, root))): runner(os.path.join(root, filename)) def excluded(self, filename, parent=None): """Check if the file should be excluded. Check if 'options.exclude' contains a pattern matching filename. """ if not self.options.exclude: return False basename = os.path.basename(filename) if filename_match(basename, self.options.exclude): return True if parent: filename = os.path.join(parent, filename) filename = os.path.abspath(filename) return filename_match(filename, self.options.exclude) def ignore_code(self, code): """Check if the error code should be ignored. If 'options.select' contains a prefix of the error code, return False. Else, if 'options.ignore' contains a prefix of the error code, return True. """ if len(code) < 4 and any(s.startswith(code) for s in self.options.select): return False return (code.startswith(self.options.ignore) and not code.startswith(self.options.select)) def get_checks(self, argument_name): """Get all the checks for this category. Find all globally visible functions where the first argument name starts with argument_name and which contain selected tests. """ checks = [] for check, attrs in _checks[argument_name].items(): (codes, args) = attrs if any(not (code and self.ignore_code(code)) for code in codes): checks.append((check.__name__, check, args)) return sorted(checks) def get_parser(prog='pycodestyle', version=__version__): """Create the parser for the program.""" parser = OptionParser(prog=prog, version=version, usage="%prog [options] input ...") parser.config_options = [ 'exclude', 'filename', 'select', 'ignore', 'max-line-length', 'max-doc-length', 'hang-closing', 'count', 'format', 'quiet', 'show-pep8', 'show-source', 'statistics', 'verbose'] parser.add_option('-v', '--verbose', default=0, action='count', help="print status messages, or debug with -vv") parser.add_option('-q', '--quiet', default=0, action='count', help="report only file names, or nothing with -qq") parser.add_option('-r', '--repeat', default=True, action='store_true', help="(obsolete) show all occurrences of the same error") parser.add_option('--first', action='store_false', dest='repeat', help="show first occurrence of each error") parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE, help="exclude files or directories which match these " "comma separated patterns (default: %default)") parser.add_option('--filename', metavar='patterns', default='*.py', help="when parsing directories, only check filenames " "matching these comma separated patterns " "(default: %default)") parser.add_option('--select', metavar='errors', default='', help="select errors and warnings (e.g. E,W6)") parser.add_option('--ignore', metavar='errors', default='', help="skip errors and warnings (e.g. E4,W) " "(default: %s)" % DEFAULT_IGNORE) parser.add_option('--show-source', action='store_true', help="show source code for each error") parser.add_option('--show-pep8', action='store_true', help="show text of PEP 8 for each error " "(implies --first)") parser.add_option('--statistics', action='store_true', help="count errors and warnings") parser.add_option('--count', action='store_true', help="print total number of errors and warnings " "to standard error and set exit code to 1 if " "total is not null") parser.add_option('--max-line-length', type='int', metavar='n', default=MAX_LINE_LENGTH, help="set maximum allowed line length " "(default: %default)") parser.add_option('--max-doc-length', type='int', metavar='n', default=None, help="set maximum allowed doc line length and perform " "these checks (unchecked if not set)") parser.add_option('--hang-closing', action='store_true', help="hang closing bracket instead of matching " "indentation of opening bracket's line") parser.add_option('--format', metavar='format', default='default', help="set the error format [default|pylint|]") parser.add_option('--diff', action='store_true', help="report changes only within line number ranges in " "the unified diff received on STDIN") group = parser.add_option_group("Testing Options") if os.path.exists(TESTSUITE_PATH): group.add_option('--testsuite', metavar='dir', help="run regression tests from dir") group.add_option('--doctest', action='store_true', help="run doctest on myself") group.add_option('--benchmark', action='store_true', help="measure processing speed") return parser def read_config(options, args, arglist, parser): """Read and parse configurations. If a config file is specified on the command line with the "--config" option, then only it is used for configuration. Otherwise, the user configuration (~/.config/pycodestyle) and any local configurations in the current directory or above will be merged together (in that order) using the read method of ConfigParser. """ config = RawConfigParser() cli_conf = options.config local_dir = os.curdir if USER_CONFIG and os.path.isfile(USER_CONFIG): if options.verbose: print('user configuration: %s' % USER_CONFIG) config.read(USER_CONFIG) parent = tail = args and os.path.abspath(os.path.commonprefix(args)) while tail: if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG): local_dir = parent if options.verbose: print('local configuration: in %s' % parent) break (parent, tail) = os.path.split(parent) if cli_conf and os.path.isfile(cli_conf): if options.verbose: print('cli configuration: %s' % cli_conf) config.read(cli_conf) pycodestyle_section = None if config.has_section(parser.prog): pycodestyle_section = parser.prog elif config.has_section('pep8'): pycodestyle_section = 'pep8' # Deprecated warnings.warn('[pep8] section is deprecated. Use [pycodestyle].') if pycodestyle_section: option_list = {o.dest: o.type or o.action for o in parser.option_list} # First, read the default values (new_options, __) = parser.parse_args([]) # Second, parse the configuration for opt in config.options(pycodestyle_section): if opt.replace('_', '-') not in parser.config_options: print(" unknown option '%s' ignored" % opt) continue if options.verbose > 1: print(" %s = %s" % (opt, config.get(pycodestyle_section, opt))) normalized_opt = opt.replace('-', '_') opt_type = option_list[normalized_opt] if opt_type in ('int', 'count'): value = config.getint(pycodestyle_section, opt) elif opt_type in ('store_true', 'store_false'): value = config.getboolean(pycodestyle_section, opt) else: value = config.get(pycodestyle_section, opt) if normalized_opt == 'exclude': value = normalize_paths(value, local_dir) setattr(new_options, normalized_opt, value) # Third, overwrite with the command-line options (options, __) = parser.parse_args(arglist, values=new_options) options.doctest = options.testsuite = False return options def process_options(arglist=None, parse_argv=False, config_file=None, parser=None, verbose=None): """Process options passed either via arglist or command line args. Passing in the ``config_file`` parameter allows other tools, such as flake8 to specify their own options to be processed in pycodestyle. """ if not parser: parser = get_parser() if not parser.has_option('--config'): group = parser.add_option_group("Configuration", description=( "The project options are read from the [%s] section of the " "tox.ini file or the setup.cfg file located in any parent folder " "of the path(s) being processed. Allowed options are: %s." % (parser.prog, ', '.join(parser.config_options)))) group.add_option('--config', metavar='path', default=config_file, help="user config file location") # Don't read the command line if the module is used as a library. if not arglist and not parse_argv: arglist = [] # If parse_argv is True and arglist is None, arguments are # parsed from the command line (sys.argv) (options, args) = parser.parse_args(arglist) options.reporter = None # If explicitly specified verbosity, override any `-v` CLI flag if verbose is not None: options.verbose = verbose if options.ensure_value('testsuite', False): args.append(options.testsuite) elif not options.ensure_value('doctest', False): if parse_argv and not args: if options.diff or any(os.path.exists(name) for name in PROJECT_CONFIG): args = ['.'] else: parser.error('input not specified') options = read_config(options, args, arglist, parser) options.reporter = parse_argv and options.quiet == 1 and FileReport options.filename = _parse_multi_options(options.filename) options.exclude = normalize_paths(options.exclude) options.select = _parse_multi_options(options.select) options.ignore = _parse_multi_options(options.ignore) if options.diff: options.reporter = DiffReport stdin = stdin_get_value() options.selected_lines = parse_udiff(stdin, options.filename, args[0]) args = sorted(options.selected_lines) return options, args def _parse_multi_options(options, split_token=','): r"""Split and strip and discard empties. Turns the following: A, B, into ["A", "B"] """ if options: return [o.strip() for o in options.split(split_token) if o.strip()] else: return options def _main(): """Parse options and run checks on Python source.""" import signal # Handle "Broken pipe" gracefully try: signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1)) except AttributeError: pass # not supported on Windows style_guide = StyleGuide(parse_argv=True) options = style_guide.options if options.doctest or options.testsuite: from testsuite.support import run_tests report = run_tests(style_guide) else: report = style_guide.check_files() if options.statistics: report.print_statistics() if options.benchmark: report.print_benchmark() if options.testsuite and not options.quiet: report.print_results() if report.total_errors: if options.count: sys.stderr.write(str(report.total_errors) + '\n') sys.exit(1) if __name__ == '__main__': _main() pycodestyle-2.5.0/LICENSE0000664000175000017500000000234613263117366016506 0ustar icordascicordasc00000000000000Copyright © 2006-2009 Johann C. Rocholl Copyright © 2009-2014 Florent Xicluna Copyright © 2014-2018 Ian Lee Licensed under the terms of the Expat License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pycodestyle-2.5.0/README.rst0000664000175000017500000000710013424054446017157 0ustar icordascicordasc00000000000000pycodestyle (formerly called pep8) - Python style guide checker =============================================================== .. image:: https://img.shields.io/travis/PyCQA/pycodestyle.svg :target: https://travis-ci.org/PyCQA/pycodestyle :alt: Build status .. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest :target: https://pycodestyle.readthedocs.io :alt: Documentation Status .. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg :target: https://pypi.org/project/pycodestyle/ :alt: Wheel Status .. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge pycodestyle is a tool to check your Python code against some of the style conventions in `PEP 8`_. .. _PEP 8: http://www.python.org/dev/peps/pep-0008/ .. note:: This package used to be called ``pep8`` but was renamed to ``pycodestyle`` to reduce confusion. Further discussion can be found `in the issue where Guido requested this change `_, or in the lightning talk at PyCon 2016 by @IanLee1521: `slides `_ `video `_. Features -------- * Plugin architecture: Adding new checks is easy. * Parseable output: Jump to error location in your editor. * Small: Just one Python file, requires only stdlib. You can use just the ``pycodestyle.py`` file for this purpose. * Comes with a comprehensive test suite. Installation ------------ You can install, upgrade, and uninstall ``pycodestyle.py`` with these commands:: $ pip install pycodestyle $ pip install --upgrade pycodestyle $ pip uninstall pycodestyle There's also a package for Debian/Ubuntu, but it's not always the latest version. Example usage and output ------------------------ :: $ pycodestyle --first optparse.py optparse.py:69:11: E401 multiple imports on one line optparse.py:77:1: E302 expected 2 blank lines, found 1 optparse.py:88:5: E301 expected 1 blank line, found 0 optparse.py:222:34: W602 deprecated form of raising exception optparse.py:347:31: E211 whitespace before '(' optparse.py:357:17: E201 whitespace after '{' optparse.py:472:29: E221 multiple spaces before operator optparse.py:544:21: W601 .has_key() is deprecated, use 'in' You can also make ``pycodestyle.py`` show the source code for each error, and even the relevant text from PEP 8:: $ pycodestyle --show-source --show-pep8 testsuite/E40.py testsuite/E40.py:2:10: E401 multiple imports on one line import os, sys ^ Imports should usually be on separate lines. Okay: import os\nimport sys E401: import sys, os Or you can display how often each error was found:: $ pycodestyle --statistics -qq Python-2.5/Lib 232 E201 whitespace after '[' 599 E202 whitespace before ')' 631 E203 whitespace before ',' 842 E211 whitespace before '(' 2531 E221 multiple spaces before operator 4473 E301 expected 1 blank line, found 0 4006 E302 expected 2 blank lines, found 1 165 E303 too many blank lines (4) 325 E401 multiple imports on one line 3615 E501 line too long (82 characters) 612 W601 .has_key() is deprecated, use 'in' 1188 W602 deprecated form of raising exception Links ----- * `Read the documentation `_ * `Fork me on GitHub `_ pycodestyle-2.5.0/setup.py0000664000175000017500000000420613424054446017206 0ustar icordascicordasc00000000000000# -*- coding: utf-8 -*- from __future__ import with_statement from setuptools import setup def get_version(): with open('pycodestyle.py') as f: for line in f: if line.startswith('__version__'): return eval(line.split('=')[-1]) def get_long_description(): descr = [] for fname in 'README.rst', 'CHANGES.txt': with open(fname) as f: descr.append(f.read()) return '\n\n'.join(descr) setup( name='pycodestyle', version=get_version(), description="Python style guide checker", long_description=get_long_description(), keywords='pycodestyle, pep8, PEP 8, PEP-8, PEP8', author='Johann C. Rocholl', author_email='johann@rocholl.net', maintainer='Ian Lee', maintainer_email='IanLee1521@gmail.com', url='https://pycodestyle.readthedocs.io/', license='Expat license', py_modules=['pycodestyle'], namespace_packages=[], include_package_data=True, zip_safe=False, python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', install_requires=[ # Broken with Python 3: https://github.com/pypa/pip/issues/650 # 'setuptools', ], entry_points={ 'console_scripts': [ 'pycodestyle = pycodestyle:_main', ], }, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Libraries :: Python Modules', ], test_suite='testsuite.test_all.suite', ) pycodestyle-2.5.0/testsuite/0000775000175000017500000000000013424056203017514 5ustar icordascicordasc00000000000000pycodestyle-2.5.0/testsuite/E22.py0000664000175000017500000000370613230023456020423 0ustar icordascicordasc00000000000000#: E221 a = 12 + 3 b = 4 + 5 #: E221 E221 x = 1 y = 2 long_variable = 3 #: E221 E221 x[0] = 1 x[1] = 2 long_variable = 3 #: E221 E221 x = f(x) + 1 y = long_variable + 2 z = x[0] + 3 #: E221:3:14 text = """ bar foo %s""" % rofl #: Okay x = 1 y = 2 long_variable = 3 #: #: E222 a = a + 1 b = b + 10 #: E222 E222 x = -1 y = -2 long_variable = 3 #: E222 E222 x[0] = 1 x[1] = 2 long_variable = 3 #: #: E223 foobart = 4 a = 3 # aligned with tab #: #: E224 a += 1 b += 1000 #: #: E225 submitted +=1 #: E225 submitted+= 1 #: E225 c =-1 #: E225 x = x /2 - 1 #: E225 c = alpha -4 #: E225 c = alpha- 4 #: E225 z = x **y #: E225 z = (x + 1) **y #: E225 z = (x + 1)** y #: E225 _1kB = _1MB >>10 #: E225 _1kB = _1MB>> 10 #: E225 E225 i=i+ 1 #: E225 E225 i=i +1 #: E225 E226 i=i+1 #: E225 E226 i =i+1 #: E225 E226 i= i+1 #: E225 E226 c = (a +b)*(a - b) #: E225 E226 c = (a+ b)*(a - b) #: #: E226 z = 2//30 #: E226 E226 c = (a+b) * (a-b) #: E226 norman = True+False #: E226 x = x*2 - 1 #: E226 x = x/2 - 1 #: E226 E226 hypot2 = x*x + y*y #: E226 c = (a + b)*(a - b) #: E226 def halves(n): return (i//2 for i in range(n)) #: E227 _1kB = _1MB>>10 #: E227 _1MB = _1kB<<10 #: E227 a = b|c #: E227 b = c&a #: E227 c = b^a #: E228 a = b%c #: E228 msg = fmt%(errno, errmsg) #: E228 msg = "Error %d occurred"%errno #: #: Okay i = i + 1 submitted += 1 x = x * 2 - 1 hypot2 = x * x + y * y c = (a + b) * (a - b) _1MiB = 2 ** 20 _1TiB = 2**30 foo(bar, key='word', *args, **kwargs) baz(**kwargs) negative = -1 spam(-1) -negative func1(lambda *args, **kw: (args, kw)) func2(lambda a, b=h[:], c=0: (a, b, c)) if not -5 < x < +5: print >>sys.stderr, "x is out of range." print >> sys.stdout, "x is an integer." x = x / 2 - 1 if alpha[:-i]: *a, b = (1, 2, 3) def squares(n): return (i**2 for i in range(n)) ENG_PREFIXES = { -6: "\u03bc", # Greek letter mu -3: "m", } #: pycodestyle-2.5.0/testsuite/test_blank_lines.py0000664000175000017500000002574513300012336023413 0ustar icordascicordasc00000000000000""" Tests for the blank_lines checker. It uses dedicated assertions which work with TestReport. """ import unittest import pycodestyle from testsuite.support import InMemoryReport class BlankLinesTestCase(unittest.TestCase): """ Common code for running blank_lines tests. """ def check(self, content): """ Run checks on `content` and return the the list of errors. """ sut = pycodestyle.StyleGuide() reporter = sut.init_report(InMemoryReport) sut.input_file( filename='in-memory-test-file.py', lines=content.splitlines(True), ) return reporter.in_memory_errors def assertNoErrors(self, actual): """ Check that the actual result from the checker has no errors. """ self.assertEqual([], actual) class TestBlankLinesDefault(BlankLinesTestCase): """ Tests for default blank with 2 blank lines for top level and 1 blank line for methods. """ def test_initial_no_blank(self): """ It will accept no blank lines at the start of the file. """ result = self.check("""def some_function(): pass """) self.assertNoErrors(result) def test_initial_lines_one_blank(self): """ It will accept 1 blank lines before the first line of actual code, even if in other places it asks for 2 """ result = self.check(""" def some_function(): pass """) self.assertNoErrors(result) def test_initial_lines_two_blanks(self): """ It will accept 2 blank lines before the first line of actual code, as normal. """ result = self.check(""" def some_function(): pass """) self.assertNoErrors(result) def test_method_less_blank_lines(self): """ It will trigger an error when less than 1 blank lin is found before method definitions. """ result = self.check("""# First comment line. class X: def a(): pass def b(): pass """) self.assertEqual([ 'E301:6:5', # b() call ], result) def test_method_less_blank_lines_comment(self): """ It will trigger an error when less than 1 blank lin is found before method definition, ignoring comments. """ result = self.check("""# First comment line. class X: def a(): pass # A comment will not make it better. def b(): pass """) self.assertEqual([ 'E301:7:5', # b() call ], result) def test_top_level_fewer_blank_lines(self): """ It will trigger an error when less 2 blank lines are found before top level definitions. """ result = self.check("""# First comment line. # Second line of comment. def some_function(): pass async def another_function(): pass def this_one_is_good(): pass class SomeCloseClass(object): pass async def this_async_is_good(): pass class AFarEnoughClass(object): pass """) self.assertEqual([ 'E302:4:1', # some_function 'E302:7:1', # another_function 'E302:14:1', # SomeCloseClass ], result) def test_top_level_more_blank_lines(self): """ It will trigger an error when more 2 blank lines are found before top level definitions. """ result = self.check("""# First comment line. # Second line of comment. def some_function(): pass def this_one_is_good(): pass class SomeFarClass(object): pass class AFarEnoughClass(object): pass """) self.assertEqual([ 'E303:6:1', # some_function 'E303:15:1', # SomeFarClass ], result) def test_method_more_blank_lines(self): """ It will trigger an error when more than 1 blank line is found before method definition """ result = self.check("""# First comment line. class SomeCloseClass(object): def oneMethod(self): pass def anotherMethod(self): pass def methodOK(self): pass def veryFar(self): pass """) self.assertEqual([ 'E303:7:5', # oneMethod 'E303:11:5', # anotherMethod 'E303:19:5', # veryFar ], result) def test_initial_lines_more_blank(self): """ It will trigger an error for more than 2 blank lines before the first line of actual code. """ result = self.check(""" def some_function(): pass """) self.assertEqual(['E303:4:1'], result) def test_blank_line_between_decorator(self): """ It will trigger an error when the decorator is followed by a blank line. """ result = self.check("""# First line. @some_decorator def some_function(): pass class SomeClass(object): @method_decorator def some_method(self): pass """) self.assertEqual(['E304:6:1', 'E304:14:5'], result) def test_blank_line_decorator(self): """ It will accept the decorators which are adjacent to the function and method definition. """ result = self.check("""# First line. @another_decorator @some_decorator def some_function(): pass class SomeClass(object): @method_decorator def some_method(self): pass """) self.assertNoErrors(result) def test_top_level_fewer_follow_lines(self): """ It will trigger an error when less than 2 blank lines are found between a top level definitions and other top level code. """ result = self.check(""" def a(): print('Something') a() """) self.assertEqual([ 'E305:5:1', # a call ], result) def test_top_level_fewer_follow_lines_comments(self): """ It will trigger an error when less than 2 blank lines are found between a top level definitions and other top level code, even if we have comments before """ result = self.check(""" def a(): print('Something') # comment # another comment # With comment still needs 2 spaces before, # as comments are ignored. a() """) self.assertEqual([ 'E305:11:1', # a call ], result) def test_top_level_good_follow_lines(self): """ It not trigger an error when 2 blank lines are found between a top level definitions and other top level code. """ result = self.check(""" def a(): print('Something') # Some comments in other parts. # More comments. # With the right spaces, # It will work, even when we have comments. a() """) self.assertNoErrors(result) def test_method_fewer_follow_lines(self): """ It will trigger an error when less than 1 blank line is found between a method and previous definitions. """ result = self.check(""" def a(): x = 1 def b(): pass """) self.assertEqual([ 'E306:4:5', # b() call ], result) def test_method_nested_fewer_follow_lines(self): """ It will trigger an error when less than 1 blank line is found between a method and previous definitions, even when nested. """ result = self.check(""" def a(): x = 2 def b(): x = 1 def c(): pass """) self.assertEqual([ 'E306:7:9', # c() call ], result) def test_method_nested_less_class(self): """ It will trigger an error when less than 1 blank line is found between a method and previous definitions, even when used to define a class. """ result = self.check(""" def a(): x = 1 class C: pass """) self.assertEqual([ 'E306:4:5', # class C definition. ], result) def test_method_nested_ok(self): """ Will not trigger an error when 1 blank line is found found between a method and previous definitions, even when nested. """ result = self.check(""" def a(): x = 2 def b(): x = 1 def c(): pass class C: pass """) self.assertNoErrors(result) class TestBlankLinesTwisted(BlankLinesTestCase): """ Tests for blank_lines with 3 blank lines for top level and 2 blank line for methods as used by the Twisted coding style. """ def setUp(self): self._original_lines_config = pycodestyle.BLANK_LINES_CONFIG.copy() pycodestyle.BLANK_LINES_CONFIG['top_level'] = 3 pycodestyle.BLANK_LINES_CONFIG['method'] = 2 def tearDown(self): pycodestyle.BLANK_LINES_CONFIG = self._original_lines_config def test_initial_lines_one_blanks(self): """ It will accept less than 3 blank lines before the first line of actual code. """ result = self.check(""" def some_function(): pass """) self.assertNoErrors(result) def test_initial_lines_tree_blanks(self): """ It will accept 3 blank lines before the first line of actual code, as normal. """ result = self.check(""" def some_function(): pass """) self.assertNoErrors(result) def test_top_level_fewer_blank_lines(self): """ It will trigger an error when less 2 blank lines are found before top level definitions. """ result = self.check("""# First comment line. # Second line of comment. def some_function(): pass async def another_function(): pass def this_one_is_good(): pass class SomeCloseClass(object): pass async def this_async_is_good(): pass class AFarEnoughClass(object): pass """) self.assertEqual([ 'E302:5:1', # some_function 'E302:9:1', # another_function 'E302:17:1', # SomeCloseClass ], result) def test_top_level_more_blank_lines(self): """ It will trigger an error when more 2 blank lines are found before top level definitions. """ result = self.check("""# First comment line. # Second line of comment. def some_function(): pass def this_one_is_good(): pass class SomeVeryFarClass(object): pass class AFarEnoughClass(object): pass """) self.assertEqual([ 'E303:7:1', # some_function 'E303:18:1', # SomeVeryFarClass ], result) def test_the_right_blanks(self): """ It will accept 3 blank for top level and 2 for nested. """ result = self.check(""" def some_function(): pass # With comments. some_other = code_here class SomeClass: ''' Docstring here. ''' def some_method(): pass def another_method(): pass # More methods. def another_method_with_comment(): pass @decorator def another_method_with_comment(): pass """) self.assertNoErrors(result) pycodestyle-2.5.0/testsuite/E26.py0000664000175000017500000000223713300012336020416 0ustar icordascicordasc00000000000000#: E261:1:5 pass # an inline comment #: E262:1:12 x = x + 1 #Increment x #: E262:1:12 x = x + 1 # Increment x #: E262:1:12 x = y + 1 #: Increment x #: E265:1:1 #Block comment a = 1 #: E265:2:1 m = 42 #! This is important mx = 42 - 42 #: E266:3:5 E266:6:5 def how_it_feel(r): ### This is a variable ### a = 42 ### Of course it is unused return #: E265:1:1 E266:2:1 ##if DEBUG: ## logging.error() #: W291:1:42 ######################################### #: #: Okay #!/usr/bin/env python pass # an inline comment x = x + 1 # Increment x y = y + 1 #: Increment x # Block comment a = 1 # Block comment1 # Block comment2 aaa = 1 # example of docstring (not parsed) def oof(): """ #foo not parsed """ #################################################################### # A SEPARATOR # #################################################################### # ################################################################ # # ####################### another separator ###################### # # ################################################################ # pycodestyle-2.5.0/testsuite/E72.py0000664000175000017500000000222013230023456020416 0ustar icordascicordasc00000000000000#: E721 if type(res) == type(42): pass #: E721 if type(res) != type(""): pass #: E721 import types if res == types.IntType: pass #: E721 import types if type(res) is not types.ListType: pass #: E721 assert type(res) == type(False) or type(res) == type(None) #: E721 assert type(res) == type([]) #: E721 assert type(res) == type(()) #: E721 assert type(res) == type((0,)) #: E721 assert type(res) == type((0)) #: E721 assert type(res) != type((1, )) #: E721 assert type(res) is type((1, )) #: E721 assert type(res) is not type((1, )) #: E211 E721 assert type(res) == type ([2, ]) #: E201 E201 E202 E721 assert type(res) == type( ( ) ) #: E201 E202 E721 assert type(res) == type( (0, ) ) #: #: Okay import types if isinstance(res, int): pass if isinstance(res, str): pass if isinstance(res, types.MethodType): pass if type(a) != type(b) or type(a) == type(ccc): pass #: E722 try: pass except: pass #: E722 try: pass except Exception: pass except: pass #: E722 E203 E271 try: pass except : pass #: Okay fake_code = """" try: do_something() except: pass """ try: pass except Exception: pass pycodestyle-2.5.0/testsuite/W60.py0000664000175000017500000000250413424054446020452 0ustar icordascicordasc00000000000000#: W601 if a.has_key("b"): print a #: W602 raise DummyError, "Message" #: W602 raise ValueError, "hello %s %s" % (1, 2) #: Okay raise type_, val, tb raise Exception, Exception("f"), t #: W603 if x <> 0: x = 0 #: W604 val = `1 + 2` #: W605:1:10 regex = '\.png$' #: W605:2:1 regex = ''' \.png$ ''' #: W605:2:6 f( '\_' ) #: W605:4:6 """ multi-line literal with \_ somewhere in the middle """ #: Okay regex = r'\.png$' regex = '\\.png$' regex = r''' \.png$ ''' regex = r''' \\.png$ ''' s = '\\' regex = '\w' # noqa regex = ''' \w ''' # noqa #: W606 async = 42 #: W606 await = 42 #: W606 await 42 #: W606 await 'test' #: W606 def async(): pass #: W606 def await(): pass #: W606 class async: pass #: W606 class await: pass #: Okay async def read_data(db): data = await db.fetch('SELECT ...') #: Okay if await fut: pass if (await fut): pass if await fut + 1: pass if (await fut) + 1: pass pair = await fut, 'spam' pair = (await fut), 'spam' with await fut, open(): pass with (await fut), open(): pass await foo()['spam'].baz()() return await coro() return (await coro()) res = await coro() ** 2 res = (await coro()) ** 2 func(a1=await coro(), a2=0) func(a1=(await coro()), a2=0) await foo() + await bar() (await foo()) + (await bar()) -await foo() -(await foo()) (await foo()) await(await foo()) pycodestyle-2.5.0/testsuite/E12.py0000664000175000017500000001522113263117366020427 0ustar icordascicordasc00000000000000#: E121 print "E121", ( "dent") #: E122 print "E122", ( "dent") #: E123 my_list = [ 1, 2, 3, 4, 5, 6, ] #: E124 print "E124", ("visual", "indent_two" ) #: E124 print "E124", ("visual", "indent_five" ) #: E124 a = (123, ) #: E129 W503 if (row < 0 or self.moduleCount <= row or col < 0 or self.moduleCount <= col): raise Exception("%s,%s - %s" % (row, col, self.moduleCount)) #: E126 print "E126", ( "dent") #: E126 print "E126", ( "dent") #: E127 print "E127", ("over-", "over-indent") #: E128 print "E128", ("visual", "hanging") #: E128 print "E128", ("under-", "under-indent") #: #: E126 my_list = [ 1, 2, 3, 4, 5, 6, ] #: E121 result = { 'key1': 'value', 'key2': 'value', } #: E126 E126 rv.update(dict.fromkeys(( 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', 'reasonComment_de', 'reasonComment_it'), '?'), "foo") #: E126 abricot = 3 + \ 4 + \ 5 + 6 #: E131 print "hello", ( "there", # "john", "dude") #: E126 part = set_mimetype(( a.get('mime_type', 'text')), 'default') #: #: E122 if True: result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', ) #: E122 if some_very_very_very_long_variable_name or var \ or another_very_long_variable_name: raise Exception() #: E122 if some_very_very_very_long_variable_name or var[0] \ or another_very_long_variable_name: raise Exception() #: E122 if True: if some_very_very_very_long_variable_name or var \ or another_very_long_variable_name: raise Exception() #: E122 if True: if some_very_very_very_long_variable_name or var[0] \ or another_very_long_variable_name: raise Exception() #: E122 dictionary = [ "is": { "nested": yes(), }, ] #: E122 setup('', scripts=[''], classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Console', 'Intended Audience :: Developers', ]) #: #: E123 W291 print "E123", ( "bad", "hanging", "close" ) # #: E123 E123 E123 result = { 'foo': [ 'bar', { 'baz': 'frop', } ] } #: E123 result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', ) #: E124 my_list = [1, 2, 3, 4, 5, 6, ] #: E124 my_list = [1, 2, 3, 4, 5, 6, ] #: E124 result = some_function_that_takes_arguments('a', 'b', 'c', 'd', 'e', 'f', ) #: E124 fooff(aaaa, cca( vvv, dadd ), fff, ) #: E124 fooff(aaaa, ccaaa( vvv, dadd ), fff, ) #: E124 d = dict('foo', help="exclude files or directories which match these " "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE ) #: E124 E128 E128 if line_removed: self.event(cr, uid, name="Removing the option for contract", description="contract line has been removed", ) #: #: E125 if foo is None and bar is "frop" and \ blah == 'yeah': blah = 'yeahnah' #: E125 # Further indentation required as indentation is not distinguishable def long_function_name( var_one, var_two, var_three, var_four): print(var_one) # #: E125 def qualify_by_address( self, cr, uid, ids, context=None, params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): """ This gets called by the web server """ #: E129 W503 if (a == 2 or b == "abc def ghi" "jkl mno"): return True #: #: E126 my_list = [ 1, 2, 3, 4, 5, 6, ] #: E126 abris = 3 + \ 4 + \ 5 + 6 #: E126 fixed = re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] + \ target[c + 1:] #: E126 E126 rv.update(dict.fromkeys(( 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', 'reasonComment_de', 'reasonComment_it'), '?'), "foo") #: E126 eat_a_dict_a_day({ "foo": "bar", }) #: E126 W503 if ( x == ( 3 ) or y == 4): pass #: E126 W503 W503 if ( x == ( 3 ) or x == ( 3) or y == 4): pass #: E131 troublesome_hash = { "hash": "value", "long": "the quick brown fox jumps over the lazy dog before doing a " "somersault", } #: #: E128 # Arguments on first line forbidden when not using vertical alignment foo = long_function_name(var_one, var_two, var_three, var_four) # #: E128 print('l.%s\t%s\t%s\t%r' % (token[2][0], pos, tokenize.tok_name[token[0]], token[1])) #: E128 def qualify_by_address(self, cr, uid, ids, context=None, params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): """ This gets called by the web server """ #: #: E128 foo(1, 2, 3, 4, 5, 6) #: E128 foo(1, 2, 3, 4, 5, 6) #: E128 foo(1, 2, 3, 4, 5, 6) #: E128 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E127 foo(1, 2, 3, 4, 5, 6) #: E128 E128 if line_removed: self.event(cr, uid, name="Removing the option for contract", description="contract line has been removed", ) #: E124 E127 E127 if line_removed: self.event(cr, uid, name="Removing the option for contract", description="contract line has been removed", ) #: E127 rv.update(d=('a', 'b', 'c'), e=42) # #: E127 W503 rv.update(d=('a' + 'b', 'c'), e=42, f=42 + 42) #: E127 W503 input1 = {'a': {'calc': 1 + 2}, 'b': 1 + 42} #: E128 W503 rv.update(d=('a' + 'b', 'c'), e=42, f=(42 + 42)) #: E123 if True: def example_issue254(): return [node.copy( ( replacement # First, look at all the node's current children. for child in node.children # Replace them. for replacement in replace(child) ), dict(name=token.undefined) )] #: E125:2:5 E125:8:5 if (""" """): pass for foo in """ abc 123 """.strip().split(): print(foo) #: E122:6:5 E122:7:5 E122:8:1 print dedent( ''' mkdir -p ./{build}/ mv ./build/ ./{build}/%(revision)s/ '''.format( build='build', # more stuff ) ) #: E701:1:8 E122:2:1 E203:4:8 E128:5:1 if True:\ print(True) print(a , end=' ') #: pycodestyle-2.5.0/testsuite/E10.py0000664000175000017500000000135613424054446020427 0ustar icordascicordasc00000000000000#: E101 W191 for a in 'abc': for b in 'xyz': print a # indented with 8 spaces print b # indented with 1 tab #: E101 E117 E122 W191 W191 if True: pass change_2_log = \ """Change 2 by slamb@testclient on 2006/04/13 21:46:23 creation """ p4change = { 2: change_2_log, } class TestP4Poller(unittest.TestCase): def setUp(self): self.setUpGetProcessOutput() return self.setUpChangeSource() def tearDown(self): pass # #: E101 E117 W191 W191 if True: foo(1, 2) #: E101 E101 W191 W191 def test_keys(self): """areas.json - All regions are accounted for.""" expected = set([ u'Norrbotten', u'V\xe4sterbotten', ]) #: E101 W191 if True: print(""" tab at start of this line """) pycodestyle-2.5.0/testsuite/E11.py0000664000175000017500000000127713424054446020432 0ustar icordascicordasc00000000000000#: E111 if x > 2: print x #: E111 E117 if True: print #: E112 if False: print #: E113 print print #: E114 E116 mimetype = 'application/x-directory' # 'httpd/unix-directory' create_date = False #: E116 E116 E116 def start(self): if True: self.master.start() # try: # self.master.start() # except MasterExit: # self.shutdown() # finally: # sys.exit() #: E115 E115 E115 E115 E115 E115 def start(self): if True: # try: # self.master.start() # except MasterExit: # self.shutdown() # finally: # sys.exit() self.master.start() #: E117 def start(): print pycodestyle-2.5.0/testsuite/E21.py0000664000175000017500000000034213040145716020416 0ustar icordascicordasc00000000000000#: E211 spam (1) #: E211 E211 dict ['key'] = list [index] #: E211 dict['key'] ['subkey'] = list[index] #: Okay spam(1) dict['key'] = list[index] # This is not prohibited by PEP8, but avoid it. class Foo (Bar, Baz): pass pycodestyle-2.5.0/testsuite/E71.py0000664000175000017500000000204613042731214020422 0ustar icordascicordasc00000000000000#: E711 if res == None: pass #: E711 if res != None: pass #: E711 if None == res: pass #: E711 if None != res: pass #: E711 if res[1] == None: pass #: E711 if res[1] != None: pass #: E711 if None != res[1]: pass #: E711 if None == res[1]: pass # #: E712 if res == True: pass #: E712 if res != False: pass #: E712 if True != res: pass #: E712 if False == res: pass #: E712 if res[1] == True: pass #: E712 if res[1] != False: pass # #: E713 if not X in Y: pass #: E713 if not X.B in Y: pass #: E713 if not X in Y and Z == "zero": pass #: E713 if X == "zero" or not Y in Z: pass # #: E714 if not X is Y: pass #: E714 if not X.B is Y: pass # #: Okay if x not in y: pass if not (X in Y or X is Z): pass if not (X in Y): pass if x is not y: pass if TrueElement.get_element(True) == TrueElement.get_element(False): pass if (True) == TrueElement or x == TrueElement: pass assert (not foo) in bar assert {'x': not foo} in bar assert [42, not foo] in bar #: pycodestyle-2.5.0/testsuite/noqa.py0000664000175000017500000000063013040145716021025 0ustar icordascicordasc00000000000000#: Okay # silence E501 url = 'https://api.github.com/repos/sigmavirus24/Todo.txt-python/branches/master?client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxx&?client_secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' # noqa # silence E128 from functools import (partial, reduce, wraps, # noqa cmp_to_key) from functools import (partial, reduce, wraps, cmp_to_key) # noqa a = 1 if a == None: # noqa pass #: pycodestyle-2.5.0/testsuite/python35.py0000664000175000017500000000011413424054446021562 0ustar icordascicordasc00000000000000#: E225 def bar(a, b)->int: pass #: Okay def baz(a, b) -> int: pass pycodestyle-2.5.0/testsuite/E23.py0000664000175000017500000000024313040145716020420 0ustar icordascicordasc00000000000000#: E231 a = (1,2) #: E231 a[b1,:] #: E231 a = [{'a':''}] #: Okay a = (4,) b = (5, ) c = {'text': text[5:]} result = { 'key1': 'value', 'key2': 'value', } pycodestyle-2.5.0/testsuite/E70.py0000664000175000017500000000076613263117366020443 0ustar icordascicordasc00000000000000#: E701:1:5 if a: a = False #: E701:1:40 if not header or header[:6] != 'bytes=': return #: E702:1:10 a = False; b = True #: E702:1:17 import bdist_egg; bdist_egg.write_safety_flag(cmd.egg_info, safe) #: E703:1:13 import shlex; #: E702:1:9 E703:1:23 del a[:]; a.append(42); #: E704:1:1 def f(x): return 2 #: E704:1:1 async def f(x): return 2 #: E704:1:1 E271:1:6 async def f(x): return 2 #: E704:1:1 E226:1:19 def f(x): return 2*x #: E704:2:5 E226:2:23 while all is round: def f(x): return 2*x #: pycodestyle-2.5.0/testsuite/support.py0000664000175000017500000001775713424054446021632 0ustar icordascicordasc00000000000000# -*- coding: utf-8 -*- import os.path import re import sys from pycodestyle import Checker, BaseReport, StandardReport, readlines SELFTEST_REGEX = re.compile(r'\b(Okay|[EW]\d{3}):\s(.*)') ROOT_DIR = os.path.dirname(os.path.dirname(__file__)) class PseudoFile(list): """Simplified file interface.""" write = list.append def getvalue(self): return ''.join(self) def flush(self): pass class TestReport(StandardReport): """Collect the results for the tests.""" def __init__(self, options): options.benchmark_keys += ['test cases', 'failed tests'] super(TestReport, self).__init__(options) self._verbose = options.verbose def error(self, line_number, offset, text, check): """Report an error, according to options.""" code = text[:4] if code in self.counters: self.counters[code] += 1 else: self.counters[code] = 1 detailed_code = '%s:%s:%s' % (code, line_number, offset + 1) # Don't care about expected errors or warnings if code in self.expected or detailed_code in self.expected: return self._deferred_print.append( (line_number, offset, detailed_code, text[5:], check.__doc__)) self.file_errors += 1 self.total_errors += 1 return code def get_file_results(self): # Check if the expected errors were found label = '%s:%s:1' % (self.filename, self.line_offset) for extended_code in self.expected: code = extended_code.split(':')[0] if not self.counters.get(code): self.file_errors += 1 self.total_errors += 1 print('%s: error %s not found' % (label, extended_code)) else: self.counters[code] -= 1 for code, extra in sorted(self.counters.items()): if code not in self._benchmark_keys: if extra and code in self.expected: self.file_errors += 1 self.total_errors += 1 print('%s: error %s found too many times (+%d)' % (label, code, extra)) # Reset counters del self.counters[code] if self._verbose and not self.file_errors: print('%s: passed (%s)' % (label, ' '.join(self.expected) or 'Okay')) self.counters['test cases'] += 1 if self.file_errors: self.counters['failed tests'] += 1 return super(TestReport, self).get_file_results() def print_results(self): results = ("%(physical lines)d lines tested: %(files)d files, " "%(test cases)d test cases%%s." % self.counters) if self.total_errors: print(results % ", %s failures" % self.total_errors) else: print(results % "") print("Test failed." if self.total_errors else "Test passed.") class InMemoryReport(BaseReport): """ Collect the results in memory, without printing anything. """ def __init__(self, options): super(InMemoryReport, self).__init__(options) self.in_memory_errors = [] def error(self, line_number, offset, text, check): """ Report an error, according to options. """ code = text[:4] self.in_memory_errors.append('%s:%s:%s' % ( code, line_number, offset + 1)) return super(InMemoryReport, self).error( line_number, offset, text, check) def selftest(options): """ Test all check functions with test cases in docstrings. """ count_failed = count_all = 0 report = BaseReport(options) counters = report.counters checks = options.physical_checks + options.logical_checks for name, check, argument_names in checks: for line in check.__doc__.splitlines(): line = line.lstrip() match = SELFTEST_REGEX.match(line) if match is None: continue code, source = match.groups() lines = [part.replace(r'\t', '\t') + '\n' for part in source.split(r'\n')] checker = Checker(lines=lines, options=options, report=report) checker.check_all() error = None if code == 'Okay': if len(counters) > len(options.benchmark_keys): codes = [key for key in counters if key not in options.benchmark_keys] error = "incorrectly found %s" % ', '.join(codes) elif not counters.get(code): error = "failed to find %s" % code # Keep showing errors for multiple tests for key in set(counters) - set(options.benchmark_keys): del counters[key] count_all += 1 if not error: if options.verbose: print("%s: %s" % (code, source)) else: count_failed += 1 print("pycodestyle.py: %s:" % error) for line in checker.lines: print(line.rstrip()) return count_failed, count_all def init_tests(pep8style): """ Initialize testing framework. A test file can provide many tests. Each test starts with a declaration. This declaration is a single line starting with '#:'. It declares codes of expected failures, separated by spaces or 'Okay' if no failure is expected. If the file does not contain such declaration, it should pass all tests. If the declaration is empty, following lines are not checked, until next declaration. Examples: * Only E224 and W701 are expected: #: E224 W701 * Following example is conform: #: Okay * Don't check these lines: #: """ report = pep8style.init_report(TestReport) runner = pep8style.input_file def run_tests(filename): """Run all the tests from a file.""" # Skip tests meant for higher versions of python ver_match = re.search(r'python(\d)(\d)?\.py$', filename) if ver_match: test_against_version = tuple(int(val or 0) for val in ver_match.groups()) if sys.version_info < test_against_version: return lines = readlines(filename) + ['#:\n'] line_offset = 0 codes = ['Okay'] testcase = [] count_files = report.counters['files'] for index, line in enumerate(lines): if not line.startswith('#:'): if codes: # Collect the lines of the test case testcase.append(line) continue if codes and index: if 'noeol' in codes: testcase[-1] = testcase[-1].rstrip('\n') codes = [c for c in codes if c not in ('Okay', 'noeol')] # Run the checker runner(filename, testcase, expected=codes, line_offset=line_offset) # output the real line numbers line_offset = index + 1 # configure the expected errors codes = line.split()[1:] # empty the test case buffer del testcase[:] report.counters['files'] = count_files + 1 return report.counters['failed tests'] pep8style.runner = run_tests def run_tests(style): options = style.options if options.doctest: import doctest fail_d, done_d = doctest.testmod(report=False, verbose=options.verbose) fail_s, done_s = selftest(options) count_failed = fail_s + fail_d if not options.quiet: count_passed = done_d + done_s - count_failed print("%d passed and %d failed." % (count_passed, count_failed)) print("Test failed." if count_failed else "Test passed.") if count_failed: sys.exit(1) if options.testsuite: init_tests(style) return style.check_files() pycodestyle-2.5.0/testsuite/test_all.py0000664000175000017500000000466613263117366021722 0ustar icordascicordasc00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import os.path import sys import unittest import pycodestyle from testsuite.support import init_tests, selftest, ROOT_DIR # Note: please only use a subset of unittest methods which were present # in Python 2.5: assert(True|False|Equal|NotEqual|Raises) class PycodestyleTestCase(unittest.TestCase): """Test the standard errors and warnings (E and W).""" def setUp(self): self._style = pycodestyle.StyleGuide( paths=[os.path.join(ROOT_DIR, 'testsuite')], select='E,W', quiet=True) def test_doctest(self): import doctest fail_d, done_d = doctest.testmod( pycodestyle, verbose=False, report=False ) self.assertTrue(done_d, msg='tests not found') self.assertFalse(fail_d, msg='%s failure(s)' % fail_d) def test_selftest(self): fail_s, done_s = selftest(self._style.options) self.assertTrue(done_s, msg='tests not found') self.assertFalse(fail_s, msg='%s failure(s)' % fail_s) def test_checkers_testsuite(self): init_tests(self._style) report = self._style.check_files() self.assertFalse(report.total_errors, msg='%s failure(s)' % report.total_errors) def test_own_dog_food(self): files = [pycodestyle.__file__.rstrip('oc'), __file__.rstrip('oc'), os.path.join(ROOT_DIR, 'setup.py')] report = self._style.init_report(pycodestyle.StandardReport) report = self._style.check_files(files) self.assertEqual(list(report.messages.keys()), ['W504'], msg='Failures: %s' % report.messages) def suite(): from testsuite import ( test_api, test_blank_lines, test_parser, test_shell, test_util, ) suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(PycodestyleTestCase)) suite.addTest(unittest.makeSuite(test_api.APITestCase)) suite.addTest(unittest.makeSuite(test_blank_lines.TestBlankLinesDefault)) suite.addTest(unittest.makeSuite(test_blank_lines.TestBlankLinesTwisted)) suite.addTest(unittest.makeSuite(test_parser.ParserTestCase)) suite.addTest(unittest.makeSuite(test_shell.ShellTestCase)) suite.addTest(unittest.makeSuite(test_util.UtilTestCase)) return suite def _main(): return unittest.TextTestRunner(verbosity=2).run(suite()) if __name__ == '__main__': sys.exit(not _main()) pycodestyle-2.5.0/testsuite/E30.py0000664000175000017500000000362113424054446020426 0ustar icordascicordasc00000000000000#: E301:5:5 class X: def a(): pass def b(): pass #: E301:6:5 class X: def a(): pass # comment def b(): pass #: #: E302:3:1 #!python # -*- coding: utf-8 -*- def a(): pass #: E302:2:1 """Main module.""" def _main(): pass #: E302:2:1 import sys def get_sys_path(): return sys.path #: E302:4:1 def a(): pass def b(): pass #: E302:6:1 def a(): pass # comment def b(): pass #: #: E302:4:1 def a(): pass async def b(): pass #: #: E303:5:1 print print #: E303:5:1 print # comment print #: E303:5:5 E303:8:5 def a(): print # comment # another comment print #: #: E304:3:1 @decorator def function(): pass #: E303:5:1 #!python """This class docstring comes on line 5. It gives error E303: too many blank lines (3) """ #: #: E305:7:1 def a(): print # comment # another comment a() #: E305:8:1 def a(): print # comment # another comment try: a() except Exception: pass #: E305:5:1 def a(): print # Two spaces before comments, too. if a(): a() #: #: E306:3:5 def a(): x = 1 def b(): pass #: E306:3:5 E306:5:9 def a(): x = 2 def b(): x = 1 def c(): pass #: E306:3:5 E306:6:5 def a(): x = 1 class C: pass x = 2 def b(): pass #: #: E305:8:1 # Example from https://github.com/PyCQA/pycodestyle/issues/400 import stuff def main(): blah, blah if __name__ == '__main__': main() # Previously just E272:1:6 E272:4:6 #: E302:4:1 E271:1:6 E271:4:6 async def x(): pass async def x(y: int = 1): pass #: E704:3:1 E302:3:1 def bar(): pass def baz(): pass #: E704:1:1 E302:2:1 def bar(): pass def baz(): pass #: E704:4:5 E306:4:5 def foo(): def bar(): pass def baz(): pass #: E704:2:5 E306:3:5 def foo(): def bar(): pass def baz(): pass pycodestyle-2.5.0/testsuite/utf-8.py0000664000175000017500000000342713300012336021027 0ustar icordascicordasc00000000000000# -*- coding: utf-8 -*- # Some random text with multi-byte characters (utf-8 encoded) # # Εδώ μάτσο κειμένων τη, τρόπο πιθανό διευθυντές ώρα μη. Νέων απλό π ροή # κι, το επί δεδομένη καθορίζουν. Πάντως ζητήσεις περιβάλλοντος ένα με, # ξέχασε αρπάζεις φαινόμενο όλη. Τρέξει εσφαλμένη χρησιμοποίησέ νέα τι. # πετάνε φακέλους, άρα με διακοπής λαμβάνουν εφαμοργής. Λες κι μειώσει # καθυστερεί. # 79 narrow chars # 01 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3[79] # 78 narrow chars (Na) + 1 wide char (W) # 01 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 情 # 3 narrow chars (Na) + 40 wide chars (W) # 情 情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情 # 3 narrow chars (Na) + 69 wide chars (W) # 情 情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情 # #: E501 W505 # 80 narrow chars (Na) # 01 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 [80] # #: E501 W505 # 78 narrow chars (Na) + 2 wide char (W) # 01 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8情情 # #: E501 W505 # 3 narrow chars (Na) + 77 wide chars (W) # 情 情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情 # pycodestyle-2.5.0/testsuite/test_api.py0000664000175000017500000003705513424054446021717 0ustar icordascicordasc00000000000000# -*- coding: utf-8 -*- import os.path import shlex import sys import unittest import pycodestyle from testsuite.support import ROOT_DIR, PseudoFile E11 = os.path.join(ROOT_DIR, 'testsuite', 'E11.py') class DummyChecker(object): def __init__(self, tree, filename): pass def run(self): if False: yield class APITestCase(unittest.TestCase): """Test the public methods.""" def setUp(self): self._saved_stdout = sys.stdout self._saved_stderr = sys.stderr self._saved_checks = pycodestyle._checks sys.stdout = PseudoFile() sys.stderr = PseudoFile() pycodestyle._checks = { k: {f: (vals[0][:], vals[1]) for (f, vals) in v.items()} for k, v in self._saved_checks.items() } def tearDown(self): sys.stdout = self._saved_stdout sys.stderr = self._saved_stderr pycodestyle._checks = self._saved_checks def reset(self): del sys.stdout[:], sys.stderr[:] def test_register_physical_check(self): def check_dummy(physical_line, line_number): if False: yield pycodestyle.register_check(check_dummy, ['Z001']) self.assertTrue(check_dummy in pycodestyle._checks['physical_line']) codes, args = pycodestyle._checks['physical_line'][check_dummy] self.assertTrue('Z001' in codes) self.assertEqual(args, ['physical_line', 'line_number']) options = pycodestyle.StyleGuide().options self.assertTrue(any(func == check_dummy for name, func, args in options.physical_checks)) def test_register_logical_check(self): def check_dummy(logical_line, tokens): if False: yield pycodestyle.register_check(check_dummy, ['Z401']) self.assertTrue(check_dummy in pycodestyle._checks['logical_line']) codes, args = pycodestyle._checks['logical_line'][check_dummy] self.assertTrue('Z401' in codes) self.assertEqual(args, ['logical_line', 'tokens']) pycodestyle.register_check(check_dummy, []) pycodestyle.register_check(check_dummy, ['Z402', 'Z403']) codes, args = pycodestyle._checks['logical_line'][check_dummy] self.assertEqual(codes, ['Z401', 'Z402', 'Z403']) self.assertEqual(args, ['logical_line', 'tokens']) options = pycodestyle.StyleGuide().options self.assertTrue(any(func == check_dummy for name, func, args in options.logical_checks)) def test_register_ast_check(self): pycodestyle.register_check(DummyChecker, ['Z701']) self.assertTrue(DummyChecker in pycodestyle._checks['tree']) codes, args = pycodestyle._checks['tree'][DummyChecker] self.assertTrue('Z701' in codes) self.assertTrue(args is None) options = pycodestyle.StyleGuide().options self.assertTrue(any(cls == DummyChecker for name, cls, args in options.ast_checks)) def test_register_invalid_check(self): class InvalidChecker(DummyChecker): def __init__(self, filename): pass def check_dummy(logical, tokens): if False: yield pycodestyle.register_check(InvalidChecker, ['Z741']) pycodestyle.register_check(check_dummy, ['Z441']) for checkers in pycodestyle._checks.values(): self.assertTrue(DummyChecker not in checkers) self.assertTrue(check_dummy not in checkers) self.assertRaises(TypeError, pycodestyle.register_check) def test_styleguide(self): report = pycodestyle.StyleGuide().check_files() self.assertEqual(report.total_errors, 0) self.assertFalse(sys.stdout) self.assertFalse(sys.stderr) self.reset() report = pycodestyle.StyleGuide().check_files(['missing-file']) stdout = sys.stdout.getvalue().splitlines() self.assertEqual(len(stdout), report.total_errors) self.assertEqual(report.total_errors, 1) # < 3.3 returns IOError; >= 3.3 returns FileNotFoundError self.assertTrue(stdout[0].startswith("missing-file:1:1: E902 ")) self.assertFalse(sys.stderr) self.reset() report = pycodestyle.StyleGuide().check_files([E11]) stdout = sys.stdout.getvalue().splitlines() self.assertEqual(len(stdout), report.total_errors) self.assertEqual(report.total_errors, 20) self.assertFalse(sys.stderr) self.reset() # Passing the paths in the constructor gives same result report = pycodestyle.StyleGuide(paths=[E11]).check_files() stdout = sys.stdout.getvalue().splitlines() self.assertEqual(len(stdout), report.total_errors) self.assertEqual(report.total_errors, 20) self.assertFalse(sys.stderr) self.reset() def test_styleguide_options(self): # Instantiate a simple checker pep8style = pycodestyle.StyleGuide(paths=[E11]) # Check style's attributes self.assertEqual(pep8style.checker_class, pycodestyle.Checker) self.assertEqual(pep8style.paths, [E11]) self.assertEqual(pep8style.runner, pep8style.input_file) self.assertEqual(pep8style.options.ignore_code, pep8style.ignore_code) self.assertEqual(pep8style.options.paths, pep8style.paths) # Check unset options for o in ('benchmark', 'config', 'count', 'diff', 'doctest', 'quiet', 'show_pep8', 'show_source', 'statistics', 'testsuite', 'verbose'): oval = getattr(pep8style.options, o) self.assertTrue(oval in (None, False), msg='%s = %r' % (o, oval)) # Check default options self.assertTrue(pep8style.options.repeat) self.assertEqual(pep8style.options.benchmark_keys, ['directories', 'files', 'logical lines', 'physical lines']) self.assertEqual(pep8style.options.exclude, ['.svn', 'CVS', '.bzr', '.hg', '.git', '__pycache__', '.tox']) self.assertEqual(pep8style.options.filename, ['*.py']) self.assertEqual(pep8style.options.format, 'default') self.assertEqual(pep8style.options.select, ()) self.assertEqual(pep8style.options.ignore, ('E226', 'E24', 'W504')) self.assertEqual(pep8style.options.max_line_length, 79) def test_styleguide_ignore_code(self): def parse_argv(argstring): _saved_argv = sys.argv sys.argv = shlex.split('pycodestyle %s /dev/null' % argstring) try: return pycodestyle.StyleGuide(parse_argv=True) finally: sys.argv = _saved_argv options = parse_argv('').options self.assertEqual(options.select, ()) self.assertEqual( options.ignore, ('E121', 'E123', 'E126', 'E226', 'E24', 'E704', 'W503', 'W504') ) options = parse_argv('--doctest').options self.assertEqual(options.select, ()) self.assertEqual(options.ignore, ()) options = parse_argv('--ignore E,W').options self.assertEqual(options.select, ()) self.assertEqual(options.ignore, ('E', 'W')) options = parse_argv('--select E,W').options self.assertEqual(options.select, ('E', 'W')) self.assertEqual(options.ignore, ('',)) options = parse_argv('--select E --ignore E24').options self.assertEqual(options.select, ('E',)) self.assertEqual(options.ignore, ('',)) options = parse_argv('--ignore E --select E24').options self.assertEqual(options.select, ('E24',)) self.assertEqual(options.ignore, ('',)) options = parse_argv('--ignore W --select E24').options self.assertEqual(options.select, ('E24',)) self.assertEqual(options.ignore, ('',)) options = parse_argv('--max-doc-length=72').options self.assertEqual(options.max_doc_length, 72) options = parse_argv('').options self.assertEqual(options.max_doc_length, None) pep8style = pycodestyle.StyleGuide(paths=[E11]) self.assertFalse(pep8style.ignore_code('E112')) self.assertFalse(pep8style.ignore_code('W191')) self.assertTrue(pep8style.ignore_code('E241')) pep8style = pycodestyle.StyleGuide(select='E', paths=[E11]) self.assertFalse(pep8style.ignore_code('E112')) self.assertTrue(pep8style.ignore_code('W191')) self.assertFalse(pep8style.ignore_code('E241')) pep8style = pycodestyle.StyleGuide(select='W', paths=[E11]) self.assertTrue(pep8style.ignore_code('E112')) self.assertFalse(pep8style.ignore_code('W191')) self.assertTrue(pep8style.ignore_code('E241')) pep8style = pycodestyle.StyleGuide(select=('F401',), paths=[E11]) self.assertEqual(pep8style.options.select, ('F401',)) self.assertEqual(pep8style.options.ignore, ('',)) self.assertFalse(pep8style.ignore_code('F')) self.assertFalse(pep8style.ignore_code('F401')) self.assertTrue(pep8style.ignore_code('F402')) def test_styleguide_excluded(self): pep8style = pycodestyle.StyleGuide(paths=[E11]) self.assertFalse(pep8style.excluded('./foo/bar')) self.assertFalse(pep8style.excluded('./foo/bar/main.py')) self.assertTrue(pep8style.excluded('./CVS')) self.assertTrue(pep8style.excluded('./.tox')) self.assertTrue(pep8style.excluded('./subdir/CVS')) self.assertTrue(pep8style.excluded('__pycache__')) self.assertTrue(pep8style.excluded('./__pycache__')) self.assertTrue(pep8style.excluded('subdir/__pycache__')) self.assertFalse(pep8style.excluded('draftCVS')) self.assertFalse(pep8style.excluded('./CVSoup')) self.assertFalse(pep8style.excluded('./CVS/subdir')) def test_styleguide_checks(self): pep8style = pycodestyle.StyleGuide(paths=[E11]) # Default lists of checkers self.assertTrue(len(pep8style.options.physical_checks) > 4) self.assertTrue(len(pep8style.options.logical_checks) > 10) self.assertEqual(len(pep8style.options.ast_checks), 0) # Sanity check for name, check, args in pep8style.options.physical_checks: self.assertEqual(check.__name__, name) self.assertEqual(args[0], 'physical_line') for name, check, args in pep8style.options.logical_checks: self.assertEqual(check.__name__, name) self.assertEqual(args[0], 'logical_line') # Do run E11 checks options = pycodestyle.StyleGuide().options self.assertTrue(any(func == pycodestyle.indentation for name, func, args in options.logical_checks)) options = pycodestyle.StyleGuide(select=['E']).options self.assertTrue(any(func == pycodestyle.indentation for name, func, args in options.logical_checks)) options = pycodestyle.StyleGuide(ignore=['W']).options self.assertTrue(any(func == pycodestyle.indentation for name, func, args in options.logical_checks)) options = pycodestyle.StyleGuide(ignore=['E12']).options self.assertTrue(any(func == pycodestyle.indentation for name, func, args in options.logical_checks)) # Do not run E11 checks options = pycodestyle.StyleGuide(select=['W']).options self.assertFalse(any(func == pycodestyle.indentation for name, func, args in options.logical_checks)) options = pycodestyle.StyleGuide(ignore=['E']).options self.assertFalse(any(func == pycodestyle.indentation for name, func, args in options.logical_checks)) options = pycodestyle.StyleGuide(ignore=['E11']).options self.assertFalse(any(func == pycodestyle.indentation for name, func, args in options.logical_checks)) def test_styleguide_init_report(self): style = pycodestyle.StyleGuide(paths=[E11]) standard_report = pycodestyle.StandardReport self.assertEqual(style.options.reporter, standard_report) self.assertEqual(type(style.options.report), standard_report) class MinorityReport(pycodestyle.BaseReport): pass report = style.init_report(MinorityReport) self.assertEqual(style.options.report, report) self.assertEqual(type(report), MinorityReport) style = pycodestyle.StyleGuide(paths=[E11], reporter=MinorityReport) self.assertEqual(type(style.options.report), MinorityReport) self.assertEqual(style.options.reporter, MinorityReport) def test_styleguide_check_files(self): pep8style = pycodestyle.StyleGuide(paths=[E11]) report = pep8style.check_files() self.assertTrue(report.total_errors) self.assertRaises(TypeError, pep8style.check_files, 42) # < 3.3 raises TypeError; >= 3.3 raises AttributeError self.assertRaises(Exception, pep8style.check_files, [42]) def test_check_unicode(self): # Do not crash if lines are Unicode (Python 2.x) pycodestyle.register_check(DummyChecker, ['Z701']) source = '#\n' if hasattr(source, 'decode'): source = source.decode('ascii') pep8style = pycodestyle.StyleGuide() count_errors = pep8style.input_file('stdin', lines=[source]) self.assertFalse(sys.stdout) self.assertFalse(sys.stderr) self.assertEqual(count_errors, 0) def test_check_nullbytes(self): pycodestyle.register_check(DummyChecker, ['Z701']) pep8style = pycodestyle.StyleGuide() count_errors = pep8style.input_file('stdin', lines=['\x00\n']) stdout = sys.stdout.getvalue() if 'SyntaxError' in stdout: # PyPy 2.2 returns a SyntaxError expected = "stdin:1:2: E901 SyntaxError" elif 'ValueError' in stdout: # Python 3.5. expected = "stdin:1:1: E901 ValueError" else: expected = "stdin:1:1: E901 TypeError" self.assertTrue(stdout.startswith(expected), msg='Output %r does not start with %r' % (stdout, expected)) self.assertFalse(sys.stderr) self.assertEqual(count_errors, 1) def test_styleguide_unmatched_triple_quotes(self): pycodestyle.register_check(DummyChecker, ['Z701']) lines = [ 'def foo():\n', ' """test docstring""\'\n', ] pep8style = pycodestyle.StyleGuide() pep8style.input_file('stdin', lines=lines) stdout = sys.stdout.getvalue() expected = 'stdin:2:5: E901 TokenError: EOF in multi-line string' self.assertTrue(expected in stdout) def test_styleguide_continuation_line_outdented(self): pycodestyle.register_check(DummyChecker, ['Z701']) lines = [ 'def foo():\n', ' pass\n', '\n', '\\\n', '\n', 'def bar():\n', ' pass\n', ] pep8style = pycodestyle.StyleGuide() count_errors = pep8style.input_file('stdin', lines=lines) self.assertEqual(count_errors, 2) stdout = sys.stdout.getvalue() expected = ( 'stdin:6:1: ' 'E122 continuation line missing indentation or outdented' ) self.assertTrue(expected in stdout) expected = 'stdin:6:1: E302 expected 2 blank lines, found 1' self.assertTrue(expected in stdout) # TODO: runner # TODO: input_file pycodestyle-2.5.0/testsuite/test_parser.py0000664000175000017500000000234213230006455022421 0ustar icordascicordasc00000000000000import os import tempfile import unittest import pycodestyle def _process_file(contents): with tempfile.NamedTemporaryFile(delete=False) as f: f.write(contents) options, args = pycodestyle.process_options(config_file=f.name) os.remove(f.name) return options, args class ParserTestCase(unittest.TestCase): def test_vanilla_ignore_parsing(self): contents = b""" [pycodestyle] ignore = E226,E24 """ options, args = _process_file(contents) self.assertEqual(options.ignore, ["E226", "E24"]) def test_multiline_ignore_parsing(self): contents = b""" [pycodestyle] ignore = E226, E24 """ options, args = _process_file(contents) self.assertEqual(options.ignore, ["E226", "E24"]) def test_trailing_comma_ignore_parsing(self): contents = b""" [pycodestyle] ignore = E226, """ options, args = _process_file(contents) self.assertEqual(options.ignore, ["E226"]) def test_multiline_trailing_comma_ignore_parsing(self): contents = b""" [pycodestyle] ignore = E226, E24, """ options, args = _process_file(contents) self.assertEqual(options.ignore, ["E226", "E24"]) pycodestyle-2.5.0/testsuite/W19.py0000664000175000017500000000534113424054446020460 0ustar icordascicordasc00000000000000#: E117 W191 if False: print # indented with 1 tab #: #: W191 y = x == 2 \ or x == 3 #: E101 E117 W191 W504 if ( x == ( 3 ) or y == 4): pass #: E101 E117 W191 if x == 2 \ or y > 1 \ or x == 3: pass #: E101 E117 W191 if x == 2 \ or y > 1 \ or x == 3: pass #: #: E101 E117 W191 W504 if (foo == bar and baz == frop): pass #: E101 E117 W191 W504 if ( foo == bar and baz == frop ): pass #: #: E101 E101 E117 W191 W191 if start[1] > end_col and not ( over_indent == 4 and indent_next): return(0, "E121 continuation line over-" "indented for visual indent") #: #: E101 E117 W191 def long_function_name( var_one, var_two, var_three, var_four): print(var_one) #: E101 E117 W191 W504 if ((row < 0 or self.moduleCount <= row or col < 0 or self.moduleCount <= col)): raise Exception("%s,%s - %s" % (row, col, self.moduleCount)) #: E101 E101 E101 E101 E117 W191 W191 W191 W191 W191 W191 if bar: return( start, 'E121 lines starting with a ' 'closing bracket should be indented ' "to match that of the opening " "bracket's line" ) # #: E101 E117 W191 W504 # you want vertical alignment, so use a parens if ((foo.bar("baz") and foo.bar("frop") )): print "yes" #: E101 E117 W191 W504 # also ok, but starting to look like LISP if ((foo.bar("baz") and foo.bar("frop"))): print "yes" #: E101 E117 W191 W504 if (a == 2 or b == "abc def ghi" "jkl mno"): return True #: E101 E117 W191 W504 if (a == 2 or b == """abc def ghi jkl mno"""): return True #: W191:2:1 W191:3:1 E101:3:2 E117 if length > options.max_line_length: return options.max_line_length, \ "E501 line too long (%d characters)" % length # #: E101 E117 W191 W191 W504 if os.path.exists(os.path.join(path, PEP8_BIN)): cmd = ([os.path.join(path, PEP8_BIN)] + self._pep8_options(targetfile)) #: W191 ''' multiline string with tab in it''' #: E101 W191 '''multiline string with tabs and spaces ''' #: Okay '''sometimes, you just need to go nuts in a multiline string and allow all sorts of crap like mixed tabs and spaces or trailing whitespace or long long long long long long long long long long long long long long long long long lines ''' # nopep8 #: Okay '''this one will get no warning even though the noqa comment is not immediately after the string ''' + foo # noqa # #: E101 E117 W191 if foo is None and bar is "frop" and \ blah == 'yeah': blah = 'yeahnah' # #: E117 W191 W191 W191 if True: foo( 1, 2) #: E117 W191 W191 W191 W191 W191 def test_keys(self): """areas.json - All regions are accounted for.""" expected = set([ u'Norrbotten', u'V\xe4sterbotten', ]) #: W191 x = [ 'abc' ] #: pycodestyle-2.5.0/testsuite/E27.py0000664000175000017500000000105313201015445020416 0ustar icordascicordasc00000000000000#: Okay True and False #: E271 True and False #: E272 True and False #: E271 if 1: #: E273 True and False #: E273 E274 True and False #: E271 a and b #: E271 1 and b #: E271 a and 2 #: E271 E272 1 and b #: E271 E272 a and 2 #: E272 this and False #: E273 a and b #: E274 a and b #: E273 E274 this and False #: Okay from u import (a, b) from v import c, d #: E271 from w import (e, f) #: E275 from w import(e, f) #: E275 from importable.module import(e, f) #: E275 try: from importable.module import(e, f) except ImportError: pass pycodestyle-2.5.0/testsuite/E40.py0000664000175000017500000000104713230023456020417 0ustar icordascicordasc00000000000000#: E401 import os, sys #: Okay import os import sys from subprocess import Popen, PIPE from myclass import MyClass from foo.bar.yourclass import YourClass import myclass import foo.bar.yourclass #: Okay __all__ = ['abc'] import foo #: Okay __version__ = "42" import foo #: Okay __author__ = "Simon Gomizelj" import foo #: Okay try: import foo except ImportError: pass else: print('imported foo') finally: print('made attempt to import foo') import bar #: E402 VERSION = '1.2.3' import foo #: E402 import foo a = 1 import bar pycodestyle-2.5.0/testsuite/E30not.py0000664000175000017500000000402713424054446021150 0ustar icordascicordasc00000000000000#: Okay class X: pass #: Okay def foo(): pass #: Okay # -*- coding: utf-8 -*- class X: pass #: Okay # -*- coding: utf-8 -*- def foo(): pass #: Okay class X: def a(): pass # comment def b(): pass # This is a # ... multi-line comment def c(): pass # This is a # ... multi-line comment @some_decorator class Y: def a(): pass # comment def b(): pass @property def c(): pass try: from nonexistent import Bar except ImportError: class Bar(object): """This is a Bar replacement""" def with_feature(f): """Some decorator""" wrapper = f if has_this_feature(f): def wrapper(*args): call_feature(args[0]) return f(*args) return wrapper try: next except NameError: def next(iterator, default): for item in iterator: return item return default def a(): pass class Foo(): """Class Foo""" def b(): pass # comment def c(): pass # comment def d(): pass # This is a # ... multi-line comment # And this one is # ... a second paragraph # ... which spans on 3 lines # Function `e` is below # NOTE: Hey this is a testcase def e(): pass def a(): print # comment print print # Comment 1 # Comment 2 # Comment 3 def b(): pass #: Okay def foo(): pass def bar(): pass class Foo(object): pass class Bar(object): pass if __name__ == '__main__': foo() #: Okay classification_errors = None #: Okay defined_properly = True #: Okay defaults = {} defaults.update({}) #: Okay def foo(x): classification = x definitely = not classification #: E704:3:1 E704:4:1 # This emits the (ignored-by-default) E704, but here we're testing # for no E30x being emitted. def bar(): pass def baz(): pass #: E704:4:5 E704:5:5 def foo(): # This emits the (ignored-by-default) E704, but here we're testing # for no E30x being emitted. def bar(): pass def baz(): pass pycodestyle-2.5.0/testsuite/latin-1.py0000664000175000017500000000023013040145716021330 0ustar icordascicordasc00000000000000# -*- coding: latin-1 -*- # Test non-UTF8 encoding latin1 = ('' '') c = ("w") pycodestyle-2.5.0/testsuite/E12not.py0000664000175000017500000003130213263117366021146 0ustar icordascicordasc00000000000000if ( x == ( 3 ) or y == 4): pass y = x == 2 \ or x == 3 if x == 2 \ or y > 1 \ or x == 3: pass if x == 2 \ or y > 1 \ or x == 3: pass #: W503 if (foo == bar and baz == frop): pass #: W503 if ( foo == bar and baz == frop ): pass a = ( ) a = (123, ) # if start[1] > end_col and not ( over_indent == 4 and indent_next): return(0, "E121 continuation line over-" "indented for visual indent") print "OK", ("visual", "indent") print "Okay", ("visual", "indent_three" ) print "a-ok", ( "there", "dude", ) print "hello", ( "there", "dude") print "hello", ( "there", # "john", "dude") print "hello", ( "there", "dude") print "hello", ( "there", "dude", ) # Aligned with opening delimiter foo = long_function_name(var_one, var_two, var_three, var_four) # # Extra indentation is not necessary. foo = long_function_name( var_one, var_two, var_three, var_four) arm = 'AAA' \ 'BBB' \ 'CCC' bbb = 'AAA' \ 'BBB' \ 'CCC' cc = ('AAA' 'BBB' 'CCC') cc = {'text': 'AAA' 'BBB' 'CCC'} cc = dict(text='AAA' 'BBB') sat = 'AAA' \ 'BBB' \ 'iii' \ 'CCC' #: W504 W504 abricot = (3 + 4 + 5 + 6) abricot = 3 + \ 4 + \ 5 + 6 part = [-1, 2, 3, 4, 5, 6] part = [-1, (2, 3, 4, 5, 6), 7, 8, 9, 0] fnct(1, 2, 3, 4, 5, 6) fnct(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) def long_function_name( var_one, var_two, var_three, var_four): print(var_one) #: W504 if ((row < 0 or self.moduleCount <= row or col < 0 or self.moduleCount <= col)): raise Exception("%s,%s - %s" % (row, col, self.moduleCount)) result = { 'foo': [ 'bar', { 'baz': 'frop', } ] } foo = my.func({ "foo": "bar", }, "baz") # fooff(aaaa, cca( vvv, dadd ), fff, ggg) fooff(aaaa, abbb, cca( vvv, aaa, dadd), "visual indentation is not a multiple of four",) # if bar: return( start, 'E121 lines starting with a ' 'closing bracket should be indented ' "to match that of the opening " "bracket's line" ) #: W504 # you want vertical alignment, so use a parens if ((foo.bar("baz") and foo.bar("frop") )): print "yes" #: W504 # also ok, but starting to look like LISP if ((foo.bar("baz") and foo.bar("frop"))): print "yes" #: W504 if (a == 2 or b == "abc def ghi" "jkl mno"): return True #: W504 if (a == 2 or b == """abc def ghi jkl mno"""): return True if length > options.max_line_length: return options.max_line_length, \ "E501 line too long (%d characters)" % length # print 'l.{line}\t{pos}\t{name}\t{text}'.format( line=token[2][0], pos=pos, name=tokenize.tok_name[token[0]], text=repr(token[1]), ) print('%-7d %s per second (%d total)' % ( options.counters[key] / elapsed, key, options.counters[key])) #: W504 if os.path.exists(os.path.join(path, PEP8_BIN)): cmd = ([os.path.join(path, PEP8_BIN)] + self._pep8_options(targetfile)) #: W504 fixed = (re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] + target[c + 1:]) #: W504 fixed = ( re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] + target[c + 1:] ) #: W504 if foo is None and bar is "frop" and \ blah == 'yeah': blah = 'yeahnah' """This is a multi-line docstring.""" if blah: # is this actually readable? :) multiline_literal = """ while True: if True: 1 """.lstrip() multiline_literal = ( """ while True: if True: 1 """.lstrip() ) multiline_literal = ( """ while True: if True: 1 """ .lstrip() ) if blah: multiline_visual = (""" while True: if True: 1 """ .lstrip()) rv = {'aaa': 42} rv.update(dict.fromkeys(( 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', 'reasonComment_de', 'reasonComment_it'), '?')) rv.update(dict.fromkeys(('qualif_nr', 'reasonComment_en', 'reasonComment_fr', 'reasonComment_de', 'reasonComment_it'), '?')) rv.update(dict.fromkeys(('qualif_nr', 'reasonComment_en', 'reasonComment_fr', 'reasonComment_de', 'reasonComment_it'), '?')) rv.update(dict.fromkeys( ('qualif_nr', 'reasonComment_en', 'reasonComment_fr', 'reasonComment_de', 'reasonComment_it'), '?' ), "foo", context={ 'alpha': 4, 'beta': 53242234, 'gamma': 17, }) rv.update( dict.fromkeys(( 'qualif_nr', 'reasonComment_en', 'reasonComment_fr', 'reasonComment_de', 'reasonComment_it'), '?'), "foo", context={ 'alpha': 4, 'beta': 53242234, 'gamma': 17, }, ) # event_obj.write(cursor, user_id, { 'user': user, 'summary': text, 'data': data, }) event_obj.write(cursor, user_id, { 'user': user, 'summary': text, 'data': {'aaa': 1, 'bbb': 2}, }) event_obj.write(cursor, user_id, { 'user': user, 'summary': text, 'data': { 'aaa': 1, 'bbb': 2}, }) event_obj.write(cursor, user_id, { 'user': user, 'summary': text, 'data': {'timestamp': now, 'content': { 'aaa': 1, 'bbb': 2 }}, }) def qualify_by_address( self, cr, uid, ids, context=None, params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): """ This gets called by the web server """ def qualify_by_address(self, cr, uid, ids, context=None, params_to_check=frozenset(QUALIF_BY_ADDRESS_PARAM)): """ This gets called by the web server """ _ipv4_re = re.compile(r'^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$') fct(""" AAA """ + status_2_string) if context: msg = """\ action: GET-CONFIG payload: ip_address: "%(ip)s" username: "%(username)s" """ % context if context: msg = """\ action: \ GET-CONFIG """ % context if context: msg = """\ action: """\ """GET-CONFIG """ % context def unicode2html(s): """Convert the characters &<>'" in string s to HTML-safe sequences. Convert newline to
too.""" return unicode((s or '').replace('&', '&') .replace('>', '>') .replace('<', '<') .replace("'", ''') .replace('"', '"') .replace('\n', '
\n')) # parser.add_option('--count', action='store_true', help="print total number of errors and warnings " "to standard error and set exit code to 1 if " "total is not null") parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE, help="exclude files or directories which match these " "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE) add_option('--count', help="print total number of errors " "to standard error total is not null") add_option('--count', help="print total number of errors " "to standard error " "total is not null") # help = ("print total number of errors " + "to standard error") help = "print total number of errors " \ "to standard error" help = u"print total number of errors " \ u"to standard error" help = ur"print total number of errors " \ ur"to standard error" help = b"print total number of errors " \ b"to standard error" help = br"print total number of errors " \ br"to standard error" d = dict('foo', help="exclude files or directories which match these " "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE) d = dict('foo', help=u"exclude files or directories which match these " u"comma separated patterns (default: %s)" % DEFAULT_EXCLUDE) d = dict('foo', help=b"exclude files or directories which match these " b"comma separated patterns (default: %s)" % DEFAULT_EXCLUDE) d = dict('foo', help=br"exclude files or directories which match these " br"comma separated patterns (default: %s)" % DEFAULT_EXCLUDE) d = dict('foo', help="exclude files or directories which match these " "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE) d = dict('foo', help="exclude files or directories which match these " "comma separated patterns (default: %s, %s)" % (DEFAULT_EXCLUDE, DEFAULT_IGNORE) ) d = dict('foo', help="exclude files or directories which match these " "comma separated patterns (default: %s, %s)" % # who knows what might happen here? (DEFAULT_EXCLUDE, DEFAULT_IGNORE) ) # parens used to allow the indenting. troublefree_hash = { "hash": "value", "long": ("the quick brown fox jumps over the lazy dog before doing a " "somersault"), "long key that tends to happen more when you're indented": ( "stringwithalongtoken you don't want to break" ), } # another accepted form troublefree_hash = { "hash": "value", "long": "the quick brown fox jumps over the lazy dog before doing " "a somersault", ("long key that tends to happen more " "when you're indented"): "stringwithalongtoken you don't want to break", } # confusing but accepted... don't do that troublesome_hash = { "hash": "value", "long": "the quick brown fox jumps over the lazy dog before doing a " "somersault", "long key that tends to happen more " "when you're indented": "stringwithalongtoken you don't want to break", } # d = dict('foo', help="exclude files or directories which match these " "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE ) d = dict('foo', help="exclude files or directories which match these " "comma separated patterns (default: %s)" % DEFAULT_EXCLUDE, foobar="this clearly should work, because it is at " "the right indent level", ) rv.update(dict.fromkeys( ('qualif_nr', 'reasonComment_en', 'reasonComment_fr', 'reasonComment_de', 'reasonComment_it'), '?'), "foo", context={'alpha': 4, 'beta': 53242234, 'gamma': 17}) def f(): try: if not Debug: print(''' If you would like to see debugging output, try: %s -d5 ''' % sys.argv[0]) d = { # comment 1: 2 } # issue 138 [ 12, # this is a multi-line inline # comment ] # issue 151 if a > b and \ c > d: moo_like_a_cow() # my_list = [ 1, 2, 3, 4, 5, 6, ] my_list = [1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', ) result = some_function_that_takes_arguments('a', 'b', 'c', 'd', 'e', 'f', ) # issue 203 dica = { ('abc' 'def'): ( 'abc'), } (abcdef[0] [1]) = ( 'abc') ('abc' 'def') == ( 'abc') # issue 214 bar( 1).zap( 2) bar( 1).zap( 2) # if True: def example_issue254(): return [node.copy( ( replacement # First, look at all the node's current children. for child in node.children # Replace them. for replacement in replace(child) ), dict(name=token.undefined) )] def valid_example(): return [node.copy(properties=dict( (key, val if val is not None else token.undefined) for key, val in node.items() ))] def other_example(): return [node.copy(properties=dict( (key, val if val is not None else token.undefined) for key, val in node.items() ))] foo([ 'bug' ]) # issue 144, finally! some_hash = { "long key that tends to happen more when you're indented": "stringwithalongtoken you don't want to break", } { 1: 999999 if True else 0, } print dedent( ''' mkdir -p ./{build}/ mv ./build/ ./{build}/%(revision)s/ '''.format( build='build', # more stuff ) ) pycodestyle-2.5.0/testsuite/test_util.py0000664000175000017500000000153713230006455022107 0ustar icordascicordasc00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import os import unittest from pycodestyle import normalize_paths class UtilTestCase(unittest.TestCase): def test_normalize_paths(self): cwd = os.getcwd() self.assertEqual(normalize_paths(''), []) self.assertEqual(normalize_paths([]), []) self.assertEqual(normalize_paths(None), []) self.assertEqual(normalize_paths(['foo']), ['foo']) self.assertEqual(normalize_paths('foo'), ['foo']) self.assertEqual(normalize_paths('foo,bar'), ['foo', 'bar']) self.assertEqual(normalize_paths('foo, bar '), ['foo', 'bar']) self.assertEqual(normalize_paths('/foo/bar,baz/../bat'), ['/foo/bar', cwd + '/bat']) self.assertEqual(normalize_paths(".pyc,\n build/*"), ['.pyc', cwd + '/build/*']) pycodestyle-2.5.0/testsuite/W39.py0000664000175000017500000000041513040145716020452 0ustar icordascicordasc00000000000000#: W391:2:1 # The next line is blank #: W391:3:1 # Two additional empty lines #: W391:4:1 W293:3:1 W293:4:1 noeol # The last lines contain space #: Okay '''there is nothing wrong with a multiline string at EOF that happens to have a blank line in it ''' pycodestyle-2.5.0/testsuite/__init__.py0000664000175000017500000000000013040145716021615 0ustar icordascicordasc00000000000000pycodestyle-2.5.0/testsuite/E73.py0000664000175000017500000000040613040145716020426 0ustar icordascicordasc00000000000000#: E731:1:1 f = lambda x: 2 * x #: E731:1:1 E226:1:16 f = lambda x: 2*x #: E731:2:5 while False: this = lambda y, z: 2 * x #: Okay f = object() f.method = lambda: 'Method' f = {} f['a'] = lambda x: x ** 2 f = [] f.append(lambda x: x ** 2) lambda: 'no-op' pycodestyle-2.5.0/testsuite/utf-8-bom.py0000664000175000017500000000012313040145716021602 0ustar icordascicordasc00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- hello = 'こんにちわ' # EOF pycodestyle-2.5.0/testsuite/E25.py0000664000175000017500000000227613266006766020445 0ustar icordascicordasc00000000000000#: E251 E251 def foo(bar = False): '''Test function with an error in declaration''' pass #: E251 foo(bar= True) #: E251 foo(bar =True) #: E251 E251 foo(bar = True) #: E251 y = bar(root= "sdasd") #: E251:2:29 parser.add_argument('--long-option', default= "/rather/long/filesystem/path/here/blah/blah/blah") #: E251:1:45 parser.add_argument('--long-option', default ="/rather/long/filesystem/path/here/blah/blah/blah") #: E251:3:8 E251:3:10 foo(True, baz=(1, 2), biz = 'foo' ) #: Okay foo(bar=(1 == 1)) foo(bar=(1 != 1)) foo(bar=(1 >= 1)) foo(bar=(1 <= 1)) (options, args) = parser.parse_args() d[type(None)] = _deepcopy_atomic # Annotated Function Definitions #: Okay def munge(input: AnyStr, sep: AnyStr = None, limit=1000, extra: Union[str, dict] = None) -> AnyStr: pass #: Okay async def add(a: int = 0, b: int = 0) -> int: return a + b # Previously E251 four times #: E271:1:6 async def add(a: int = 0, b: int = 0) -> int: return a + b #: E252:1:15 E252:1:16 E252:1:27 E252:1:36 def add(a: int=0, b: int =0, c: int= 0) -> int: return a + b + c #: Okay def add(a: int = _default(name='f')): return a pycodestyle-2.5.0/testsuite/E50.py0000664000175000017500000000607113300012336020413 0ustar icordascicordasc00000000000000#: E501 a = '12345678901234567890123456789012345678901234567890123456789012345678901234567890' #: E501 a = '1234567890123456789012345678901234567890123456789012345678901234567890' or \ 6 #: E501 a = 7 or \ '1234567890123456789012345678901234567890123456789012345678901234567890' or \ 6 #: E501 E501 a = 7 or \ '1234567890123456789012345678901234567890123456789012345678901234567890' or \ '1234567890123456789012345678901234567890123456789012345678901234567890' or \ 6 #: E501 a = '1234567890123456789012345678901234567890123456789012345678901234567890' # \ #: E502 a = ('123456789012345678901234567890123456789012345678901234567890123456789' \ '01234567890') #: E502 a = ('AAA \ BBB' \ 'CCC') #: E502 if (foo is None and bar is "e000" and \ blah == 'yeah'): blah = 'yeahnah' # #: Okay a = ('AAA' 'BBB') a = ('AAA \ BBB' 'CCC') a = 'AAA' \ 'BBB' \ 'CCC' a = ('AAA\ BBBBBBBBB\ CCCCCCCCC\ DDDDDDDDD') # #: Okay if aaa: pass elif bbb or \ ccc: pass ddd = \ ccc ('\ ' + ' \ ') (''' ''' + ' \ ') #: E501 E225 E226 very_long_identifiers=and_terrible_whitespace_habits(are_no_excuse+for_long_lines) # #: E501 W505 '''multiline string with a long long long long long long long long long long long long long long long long line ''' #: E501 W505 '''same thing, but this time without a terminal newline in the string long long long long long long long long long long long long long long long long line''' # # issue 224 (unavoidable long lines in docstrings) #: Okay """ I'm some great documentation. Because I'm some great documentation, I'm going to give you a reference to some valuable information about some API that I'm calling: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx """ #: E501 W505 """ longnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaces""" #: E501 W505 # Regression test for #622 def foo(): """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis pulvinar vitae """ #: Okay """ This almost_empty_line """ #: E501 W505 """ This almost_empty_line """ #: E501 W505 # A basic comment # with a long long long long long long long long long long long long long long long long line # #: Okay # I'm some great comment. Because I'm so great, I'm going to give you a # reference to some valuable information about some API that I'm # calling: # # http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx import this # longnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaces # #: Okay # This # almost_empty_line # #: E501 W505 # This # almost_empty_line # #: Okay #!/reallylongpath/toexecutable --maybe --with --some ARGUMENTS TO DO WITH WHAT EXECUTABLE TO RUN pycodestyle-2.5.0/testsuite/E20.py0000664000175000017500000000136313040145716020421 0ustar icordascicordasc00000000000000#: E201:1:6 spam( ham[1], {eggs: 2}) #: E201:1:10 spam(ham[ 1], {eggs: 2}) #: E201:1:15 spam(ham[1], { eggs: 2}) #: Okay spam(ham[1], {eggs: 2}) #: #: E202:1:23 spam(ham[1], {eggs: 2} ) #: E202:1:22 spam(ham[1], {eggs: 2 }) #: E202:1:11 spam(ham[1 ], {eggs: 2}) #: Okay spam(ham[1], {eggs: 2}) result = func( arg1='some value', arg2='another value', ) result = func( arg1='some value', arg2='another value' ) result = [ item for item in items if item > 5 ] #: #: E203:1:10 if x == 4 : print x, y x, y = y, x #: E203:2:15 E702:2:16 if x == 4: print x, y ; x, y = y, x #: E203:3:13 if x == 4: print x, y x, y = y , x #: Okay if x == 4: print x, y x, y = y, x a[b1, :] == a[b1, ...] b = a[:, b1] #: pycodestyle-2.5.0/testsuite/E90.py0000664000175000017500000000067113424054446020436 0ustar icordascicordasc00000000000000#: E901 } #: E901 = [x #: E901 E101 E117 W191 while True: try: pass except: print 'Whoops' #: E122 E225 E251 E251 # Do not crash if code is invalid if msg: errmsg = msg % progress.get(cr_dbname)) def lasting(self, duration=300): progress = self._progress.setdefault('foo', {} #: Okay # Issue #119 # Do not crash with Python2 if the line endswith '\r\r\n' EMPTY_SET = set() SET_TYPE = type(EMPTY_SET) toto = 0 + 0 #: pycodestyle-2.5.0/testsuite/python3.py0000664000175000017500000000150213230023456021467 0ustar icordascicordasc00000000000000#!/usr/bin/env python3 from typing import ClassVar, List # Annotated function (Issue #29) def foo(x: int) -> int: return x + 1 # Annotated variables #575 CONST: int = 42 class Class: # Camel-caes cls_var: ClassVar[str] for_var: ClassVar[str] while_var: ClassVar[str] def_var: ClassVar[str] if_var: ClassVar[str] elif_var: ClassVar[str] else_var: ClassVar[str] try_var: ClassVar[str] except_var: ClassVar[str] finally_var: ClassVar[str] with_var: ClassVar[str] forVar: ClassVar[str] whileVar: ClassVar[str] defVar: ClassVar[str] ifVar: ClassVar[str] elifVar: ClassVar[str] elseVar: ClassVar[str] tryVar: ClassVar[str] exceptVar: ClassVar[str] finallyVar: ClassVar[str] withVar: ClassVar[str] def m(self): xs: List[int] = [] pycodestyle-2.5.0/testsuite/W29.py0000664000175000017500000000056713040145716020461 0ustar icordascicordasc00000000000000#: Okay # 情 #: W291:1:6 print #: W293:2:1 class Foo(object): bang = 12 #: W291:2:35 '''multiline string with trailing whitespace''' #: W292:1:36 noeol # This line doesn't have a linefeed #: W292:1:5 E225:1:2 noeol 1+ 1 #: W292:1:27 E261:1:12 noeol import this # no line feed #: W292:3:22 noeol class Test(object): def __repr__(self): return 'test' pycodestyle-2.5.0/testsuite/test_shell.py0000664000175000017500000001721713424054446022253 0ustar icordascicordasc00000000000000# -*- coding: utf-8 -*- import os.path import sys import unittest import pycodestyle from testsuite.support import ROOT_DIR, PseudoFile class ShellTestCase(unittest.TestCase): """Test the usual CLI options and output.""" def setUp(self): self._saved_argv = sys.argv self._saved_stdout = sys.stdout self._saved_stderr = sys.stderr self._saved_pconfig = pycodestyle.PROJECT_CONFIG self._saved_cpread = pycodestyle.RawConfigParser._read self._saved_stdin_get_value = pycodestyle.stdin_get_value self._config_filenames = [] self.stdin = '' sys.argv = ['pycodestyle'] sys.stdout = PseudoFile() sys.stderr = PseudoFile() def fake_config_parser_read(cp, fp, filename): self._config_filenames.append(filename) pycodestyle.RawConfigParser._read = fake_config_parser_read pycodestyle.stdin_get_value = self.stdin_get_value def tearDown(self): sys.argv = self._saved_argv sys.stdout = self._saved_stdout sys.stderr = self._saved_stderr pycodestyle.PROJECT_CONFIG = self._saved_pconfig pycodestyle.RawConfigParser._read = self._saved_cpread pycodestyle.stdin_get_value = self._saved_stdin_get_value def stdin_get_value(self): return self.stdin def pycodestyle(self, *args): del sys.stdout[:], sys.stderr[:] sys.argv[1:] = args try: pycodestyle._main() errorcode = None except SystemExit: errorcode = sys.exc_info()[1].code return sys.stdout.getvalue(), sys.stderr.getvalue(), errorcode def test_print_usage(self): stdout, stderr, errcode = self.pycodestyle('--help') self.assertFalse(errcode) self.assertFalse(stderr) self.assertTrue(stdout.startswith( "Usage: pycodestyle [options] input" )) stdout, stderr, errcode = self.pycodestyle('--version') self.assertFalse(errcode) self.assertFalse(stderr) self.assertEqual(stdout.count('\n'), 1) stdout, stderr, errcode = self.pycodestyle('--obfuscated') self.assertEqual(errcode, 2) self.assertEqual(stderr.splitlines(), ["Usage: pycodestyle [options] input ...", "", "pycodestyle: error: no such option: --obfuscated"]) self.assertFalse(stdout) self.assertFalse(self._config_filenames) def test_check_simple(self): E11 = os.path.join(ROOT_DIR, 'testsuite', 'E11.py') stdout, stderr, errcode = self.pycodestyle(E11) stdout = stdout.splitlines() self.assertEqual(errcode, 1) self.assertFalse(stderr) self.assertEqual(len(stdout), 20) for line, num, col in zip(stdout, (3, 6, 6, 9, 12), (3, 6, 6, 1, 5)): path, x, y, msg = line.split(':') self.assertTrue(path.endswith(E11)) self.assertEqual(x, str(num)) self.assertEqual(y, str(col)) self.assertTrue(msg.startswith(' E11')) # Config file read from the pycodestyle's setup.cfg config_filenames = [os.path.basename(p) for p in self._config_filenames] self.assertTrue('setup.cfg' in config_filenames) def test_check_stdin(self): pycodestyle.PROJECT_CONFIG = () stdout, stderr, errcode = self.pycodestyle('-') self.assertFalse(errcode) self.assertFalse(stderr) self.assertFalse(stdout) self.stdin = 'import os, sys\n' stdout, stderr, errcode = self.pycodestyle('-') stdout = stdout.splitlines() self.assertEqual(errcode, 1) self.assertFalse(stderr) self.assertEqual(stdout, ['stdin:1:10: E401 multiple imports on one line']) def test_check_non_existent(self): self.stdin = 'import os, sys\n' stdout, stderr, errcode = self.pycodestyle('fictitious.py') self.assertEqual(errcode, 1) self.assertFalse(stderr) self.assertTrue(stdout.startswith('fictitious.py:1:1: E902 ')) def test_check_noarg(self): # issue #170: do not read stdin by default pycodestyle.PROJECT_CONFIG = () stdout, stderr, errcode = self.pycodestyle() self.assertEqual(errcode, 2) self.assertEqual(stderr.splitlines(), ["Usage: pycodestyle [options] input ...", "", "pycodestyle: error: input not specified"]) self.assertFalse(self._config_filenames) def test_check_diff(self): pycodestyle.PROJECT_CONFIG = () diff_lines = [ "--- testsuite/E11.py 2006-06-01 08:49:50 +0500", "+++ testsuite/E11.py 2008-04-06 17:36:29 +0500", "@@ -2,4 +2,7 @@", " if x > 2:", " print x", "+#: E111", "+if True:", "+ print", " #: E112", " if False:", "", ] self.stdin = '\n'.join(diff_lines) stdout, stderr, errcode = self.pycodestyle('--diff') stdout = stdout.splitlines() self.assertEqual(errcode, 1) self.assertFalse(stderr) for line, num, col in zip(stdout, (3, 6), (3, 6)): path, x, y, msg = line.split(':') self.assertEqual(x, str(num)) self.assertEqual(y, str(col)) self.assertTrue(msg.startswith(' E11')) diff_lines[:2] = ["--- a/testsuite/E11.py 2006-06-01 08:49 +0400", "+++ b/testsuite/E11.py 2008-04-06 17:36 +0400"] self.stdin = '\n'.join(diff_lines) stdout, stderr, errcode = self.pycodestyle('--diff') stdout = stdout.splitlines() self.assertEqual(errcode, 1) self.assertFalse(stderr) for line, num, col in zip(stdout, (3, 6), (3, 6)): path, x, y, msg = line.split(':') self.assertEqual(x, str(num)) self.assertEqual(y, str(col)) self.assertTrue(msg.startswith(' E11')) # issue #127, #137: one-line chunks diff_lines[:-1] = ["diff --git a/testsuite/E11.py b/testsuite/E11.py", "index 8735e25..2ecb529 100644", "--- a/testsuite/E11.py", "+++ b/testsuite/E11.py", "@@ -5,0 +6 @@ if True:", "+ print"] self.stdin = '\n'.join(diff_lines) stdout, stderr, errcode = self.pycodestyle('--diff') stdout = stdout.splitlines() self.assertEqual(errcode, 1) self.assertFalse(stderr) self.assertTrue('testsuite/E11.py:6:6: E111 ' in stdout[0]) self.assertTrue('testsuite/E11.py:6:6: E117 ' in stdout[1]) # missing '--diff' self.stdin = '\n'.join(diff_lines) stdout, stderr, errcode = self.pycodestyle() self.assertEqual(errcode, 2) self.assertFalse(stdout) self.assertTrue(stderr.startswith( 'Usage: pycodestyle [options] input ...' )) # no matching file in the diff diff_lines[3] = "+++ b/testsuite/lost/E11.py" self.stdin = '\n'.join(diff_lines) stdout, stderr, errcode = self.pycodestyle('--diff') self.assertFalse(errcode) self.assertFalse(stdout) self.assertFalse(stderr) for index, diff_line in enumerate(diff_lines, 0): diff_line = diff_line.replace('a/', 'i/') diff_lines[index] = diff_line.replace('b/', 'w/') self.stdin = '\n'.join(diff_lines) stdout, stderr, errcode = self.pycodestyle('--diff') self.assertFalse(errcode) self.assertFalse(stdout) self.assertFalse(stderr) pycodestyle-2.5.0/testsuite/E24.py0000664000175000017500000000033013040145716020416 0ustar icordascicordasc00000000000000#: E241 a = (1, 2) #: Okay b = (1, 20) #: E242 a = (1, 2) # tab before 2 #: Okay b = (1, 20) # space before 20 #: E241 E241 E241 # issue 135 more_spaces = [a, b, ef, +h, c, -d] pycodestyle-2.5.0/pycodestyle.egg-info/0000775000175000017500000000000013424056203021521 5ustar icordascicordasc00000000000000pycodestyle-2.5.0/pycodestyle.egg-info/namespace_packages.txt0000664000175000017500000000000113424056203026043 0ustar icordascicordasc00000000000000 pycodestyle-2.5.0/pycodestyle.egg-info/entry_points.txt0000664000175000017500000000006313424056203025016 0ustar icordascicordasc00000000000000[console_scripts] pycodestyle = pycodestyle:_main pycodestyle-2.5.0/pycodestyle.egg-info/dependency_links.txt0000664000175000017500000000000113424056203025567 0ustar icordascicordasc00000000000000 pycodestyle-2.5.0/pycodestyle.egg-info/SOURCES.txt0000664000175000017500000000232313424056203023405 0ustar icordascicordasc00000000000000CHANGES.txt CONTRIBUTING.rst LICENSE MANIFEST.in README.rst dev-requirements.txt pycodestyle.py setup.cfg setup.py docs/Makefile docs/advanced.rst docs/api.rst docs/conf.py docs/developer.rst docs/index.rst docs/intro.rst docs/make.bat pycodestyle.egg-info/PKG-INFO pycodestyle.egg-info/SOURCES.txt pycodestyle.egg-info/dependency_links.txt pycodestyle.egg-info/entry_points.txt pycodestyle.egg-info/namespace_packages.txt pycodestyle.egg-info/not-zip-safe pycodestyle.egg-info/top_level.txt testsuite/E10.py testsuite/E11.py testsuite/E12.py testsuite/E12not.py testsuite/E20.py testsuite/E21.py testsuite/E22.py testsuite/E23.py testsuite/E24.py testsuite/E25.py testsuite/E26.py testsuite/E27.py testsuite/E30.py testsuite/E30not.py testsuite/E40.py testsuite/E50.py testsuite/E70.py testsuite/E71.py testsuite/E72.py testsuite/E73.py testsuite/E90.py testsuite/W19.py testsuite/W29.py testsuite/W39.py testsuite/W60.py testsuite/__init__.py testsuite/latin-1.py testsuite/noqa.py testsuite/python3.py testsuite/python35.py testsuite/support.py testsuite/test_all.py testsuite/test_api.py testsuite/test_blank_lines.py testsuite/test_parser.py testsuite/test_shell.py testsuite/test_util.py testsuite/utf-8-bom.py testsuite/utf-8.pypycodestyle-2.5.0/pycodestyle.egg-info/PKG-INFO0000664000175000017500000010724713424056203022631 0ustar icordascicordasc00000000000000Metadata-Version: 1.2 Name: pycodestyle Version: 2.5.0 Summary: Python style guide checker Home-page: https://pycodestyle.readthedocs.io/ Author: Ian Lee Author-email: IanLee1521@gmail.com License: Expat license Description-Content-Type: UNKNOWN Description: pycodestyle (formerly called pep8) - Python style guide checker =============================================================== .. image:: https://img.shields.io/travis/PyCQA/pycodestyle.svg :target: https://travis-ci.org/PyCQA/pycodestyle :alt: Build status .. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest :target: https://pycodestyle.readthedocs.io :alt: Documentation Status .. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg :target: https://pypi.org/project/pycodestyle/ :alt: Wheel Status .. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge pycodestyle is a tool to check your Python code against some of the style conventions in `PEP 8`_. .. _PEP 8: http://www.python.org/dev/peps/pep-0008/ .. note:: This package used to be called ``pep8`` but was renamed to ``pycodestyle`` to reduce confusion. Further discussion can be found `in the issue where Guido requested this change `_, or in the lightning talk at PyCon 2016 by @IanLee1521: `slides `_ `video `_. Features -------- * Plugin architecture: Adding new checks is easy. * Parseable output: Jump to error location in your editor. * Small: Just one Python file, requires only stdlib. You can use just the ``pycodestyle.py`` file for this purpose. * Comes with a comprehensive test suite. Installation ------------ You can install, upgrade, and uninstall ``pycodestyle.py`` with these commands:: $ pip install pycodestyle $ pip install --upgrade pycodestyle $ pip uninstall pycodestyle There's also a package for Debian/Ubuntu, but it's not always the latest version. Example usage and output ------------------------ :: $ pycodestyle --first optparse.py optparse.py:69:11: E401 multiple imports on one line optparse.py:77:1: E302 expected 2 blank lines, found 1 optparse.py:88:5: E301 expected 1 blank line, found 0 optparse.py:222:34: W602 deprecated form of raising exception optparse.py:347:31: E211 whitespace before '(' optparse.py:357:17: E201 whitespace after '{' optparse.py:472:29: E221 multiple spaces before operator optparse.py:544:21: W601 .has_key() is deprecated, use 'in' You can also make ``pycodestyle.py`` show the source code for each error, and even the relevant text from PEP 8:: $ pycodestyle --show-source --show-pep8 testsuite/E40.py testsuite/E40.py:2:10: E401 multiple imports on one line import os, sys ^ Imports should usually be on separate lines. Okay: import os\nimport sys E401: import sys, os Or you can display how often each error was found:: $ pycodestyle --statistics -qq Python-2.5/Lib 232 E201 whitespace after '[' 599 E202 whitespace before ')' 631 E203 whitespace before ',' 842 E211 whitespace before '(' 2531 E221 multiple spaces before operator 4473 E301 expected 1 blank line, found 0 4006 E302 expected 2 blank lines, found 1 165 E303 too many blank lines (4) 325 E401 multiple imports on one line 3615 E501 line too long (82 characters) 612 W601 .has_key() is deprecated, use 'in' 1188 W602 deprecated form of raising exception Links ----- * `Read the documentation `_ * `Fork me on GitHub `_ Changelog ========= 2.5.0 (2019-01-29) ------------------ New checks: * E117: Over-indented code blocks * W505: Maximum doc-string length only when configured with --max-doc-length Changes: * Remove support for EOL Python 2.6 and 3.3. PR #720. * Add E117 error for over-indented code blocks. * Allow W605 to be silenced by `# noqa` and fix the position reported by W605 * Allow users to omit blank lines around one-liner definitions of classes and functions * Include the function return annotation (``->``) as requiring surrounding whitespace only on Python 3 * Verify that only names can follow ``await``. Previously we allowed numbers and strings. * Add support for Python 3.7 * Fix detection of annotated argument defaults for E252 * Cprrect the position reported by W504 2.4.0 (2018-04-10) ------------------ New checks: * Add W504 warning for checking that a break doesn't happen after a binary operator. This check is ignored by default. PR #502. * Add W605 warning for invalid escape sequences in string literals. PR #676. * Add W606 warning for 'async' and 'await' reserved keywords being introduced in Python 3.7. PR #684. * Add E252 error for missing whitespace around equal sign in type annotated function arguments with defaults values. PR #717. Changes: * An internal bisect search has replaced a linear search in order to improve efficiency. PR #648. * pycodestyle now uses PyPI trove classifiers in order to document supported python versions on PyPI. PR #654. * 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as the former is legacy. PR #653. * pycodestyle now handles very long lines much more efficiently for python 3.2+. Fixes #643. PR #644. * You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve verbosity. PR #663. * The distribution of pycodestyle now includes the license text in order to comply with open source licenses which require this. PR #694. * 'maximum_line_length' now ignores shebang ('#!') lines. PR #736. * Add configuration option for the allowed number of blank lines. It is implemented as a top level dictionary which can be easily overwritten. Fixes #732. PR #733. Bugs: * Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused by an invalid escape sequence. PR #625. * Correctly report E501 when the first line of a docstring is too long. Resolves #622. PR #630. * Support variable annotation when variable start by a keyword, such as class variable type annotations in python 3.6. PR #640. * pycodestyle internals have been changed in order to allow 'python3 -m cProfile' to report correct metrics. PR #647. * Fix a spelling mistake in the description of E722. PR #697. * 'pycodestyle --diff' now does not break if your 'gitconfig' enables 'mnemonicprefix'. PR #706. 2.3.1 (2017-01-31) ------------------ Bugs: * Fix regression in detection of E302 and E306; #618, #620 2.3.0 (2017-01-30) ------------------ New Checks: * Add E722 warning for bare ``except`` clauses * Report E704 for async function definitions (``async def``) Bugs: * Fix another E305 false positive for variables beginning with "class" or "def" * Fix detection of multiple spaces between ``async`` and ``def`` * Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for variable annotations. 2.2.0 (2016-11-14) ------------------ Announcements: * Added Make target to obtain proper tarball file permissions; #599 Bugs: * Fixed E305 regression caused by #400; #593 2.1.0 (2016-11-04) ------------------ Announcements: * Change all references to the pep8 project to say pycodestyle; #530 Changes: * Report E302 for blank lines before an "async def"; #556 * Update our list of tested and supported Python versions which are 2.6, 2.7, 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy. * Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'. * Report E741 on 'global' and 'nonlocal' statements, as well as prohibited single-letter variables. * Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591 * Report E722 when bare except clause is used; #579 Bugs: * Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561 * Require two blank lines after toplevel def, class; #536 * Remove accidentally quadratic computation based on the number of colons. This will make pycodestyle faster in some cases; #314 2.0.0 (2016-05-31) ------------------ Announcements: * Repository renamed to `pycodestyle`; Issue #466 / #481. * Added joint Code of Conduct as member of PyCQA; #483 Changes: * Added tox test support for Python 3.5 and pypy3 * Added check E275 for whitespace on `from ... import ...` lines; #489 / #491 * Added W503 to the list of codes ignored by default ignore list; #498 * Removed use of project level `.pep8` configuration file; #364 Bugs: * Fixed bug with treating `~` operator as binary; #383 / #384 * Identify binary operators as unary; #484 / #485 1.7.0 (2016-01-12) ------------------ Announcements: * Repository moved to PyCQA Organization on GitHub: https://github.com/pycqa/pep8 Changes: * Reverted the fix in #368, "options passed on command line are only ones accepted" feature. This has many unintended consequences in pep8 and flake8 and needs to be reworked when I have more time. * Added support for Python 3.5. (Issue #420 & #459) * Added support for multi-line config_file option parsing. (Issue #429) * Improved parameter parsing. (Issues #420 & #456) Bugs: * Fixed BytesWarning on Python 3. (Issue #459) 1.6.2 (2015-02-15) ------------------ Changes: * Added check for breaking around a binary operator. (Issue #197, Pull #305) Bugs: * Restored config_file parameter in process_options(). (Issue #380) 1.6.1 (2015-02-08) ------------------ Changes: * Assign variables before referenced. (Issue #287) Bugs: * Exception thrown due to unassigned ``local_dir`` variable. (Issue #377) 1.6.0 (2015-02-06) ------------------ News: * Ian Lee joined the project as a maintainer. Changes: * Report E731 for lambda assignment. (Issue #277) * Report E704 for one-liner def instead of E701. Do not report this error in the default configuration. (Issue #277) * Replace codes E111, E112 and E113 with codes E114, E115 and E116 for bad indentation of comments. (Issue #274) * Report E266 instead of E265 when the block comment starts with multiple ``#``. (Issue #270) * Report E402 for import statements not at the top of the file. (Issue #264) * Do not enforce whitespaces around ``**`` operator. (Issue #292) * Strip whitespace from around paths during normalization. (Issue #339 / #343) * Update ``--format`` documentation. (Issue #198 / Pull Request #310) * Add ``.tox/`` to default excludes. (Issue #335) * Do not report E121 or E126 in the default configuration. (Issues #256 / #316) * Allow spaces around the equals sign in an annotated function. (Issue #357) * Allow trailing backslash if in an inline comment. (Issue #374) * If ``--config`` is used, only that configuration is processed. Otherwise, merge the user and local configurations are merged. (Issue #368 / #369) Bug fixes: * Don't crash if Checker.build_tokens_line() returns None. (Issue #306) * Don't crash if os.path.expanduser() throws an ImportError. (Issue #297) * Missing space around keyword parameter equal not always reported, E251. (Issue #323) * Fix false positive E711/E712/E713. (Issues #330 and #336) * Do not skip physical checks if the newline is escaped. (Issue #319) * Flush sys.stdout to avoid race conditions with printing. See flake8 bug: https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363) 1.5.7 (2014-05-29) ------------------ Bug fixes: * Skip the traceback on "Broken pipe" signal. (Issue #275) * Do not exit when an option in ``setup.cfg`` or ``tox.ini`` is not recognized. * Check the last line even if it does not end with a newline. (Issue #286) * Always open files in universal newlines mode in Python 2. (Issue #288) 1.5.6 (2014-04-14) ------------------ Bug fixes: * Check the last line even if it has no end-of-line. (Issue #273) 1.5.5 (2014-04-10) ------------------ Bug fixes: * Fix regression with E22 checks and inline comments. (Issue #271) 1.5.4 (2014-04-07) ------------------ Bug fixes: * Fix negative offset with E303 before a multi-line docstring. (Issue #269) 1.5.3 (2014-04-04) ------------------ Bug fixes: * Fix wrong offset computation when error is on the last char of a physical line. (Issue #268) 1.5.2 (2014-04-04) ------------------ Changes: * Distribute a universal wheel file. Bug fixes: * Report correct line number for E303 with comments. (Issue #60) * Do not allow newline after parameter equal. (Issue #252) * Fix line number reported for multi-line strings. (Issue #220) * Fix false positive E121/E126 with multi-line strings. (Issue #265) * Fix E501 not detected in comments with Python 2.5. * Fix caret position with ``--show-source`` when line contains tabs. 1.5.1 (2014-03-27) ------------------ Bug fixes: * Fix a crash with E125 on multi-line strings. (Issue #263) 1.5 (2014-03-26) ---------------- Changes: * Report E129 instead of E125 for visually indented line with same indent as next logical line. (Issue #126) * Report E265 for space before block comment. (Issue #190) * Report E713 and E714 when operators ``not in`` and ``is not`` are recommended. (Issue #236) * Allow long lines in multiline strings and comments if they cannot be wrapped. (Issue #224). * Optionally disable physical line checks inside multiline strings, using ``# noqa``. (Issue #242) * Change text for E121 to report "continuation line under-indented for hanging indent" instead of indentation not being a multiple of 4. * Report E131 instead of E121 / E126 if the hanging indent is not consistent within the same continuation block. It helps when error E121 or E126 is in the ``ignore`` list. * Report E126 instead of E121 when the continuation line is hanging with extra indentation, even if indentation is not a multiple of 4. Bug fixes: * Allow the checkers to report errors on empty files. (Issue #240) * Fix ignoring too many checks when ``--select`` is used with codes declared in a flake8 extension. (Issue #216) * Fix regression with multiple brackets. (Issue #214) * Fix ``StyleGuide`` to parse the local configuration if the keyword argument ``paths`` is specified. (Issue #246) * Fix a false positive E124 for hanging indent. (Issue #254) * Fix a false positive E126 with embedded colon. (Issue #144) * Fix a false positive E126 when indenting with tabs. (Issue #204) * Fix behaviour when ``exclude`` is in the configuration file and the current directory is not the project directory. (Issue #247) * The logical checks can return ``None`` instead of an empty iterator. (Issue #250) * Do not report multiple E101 if only the first indentation starts with a tab. (Issue #237) * Fix a rare false positive W602. (Issue #34) 1.4.6 (2013-07-02) ------------------ Changes: * Honor ``# noqa`` for errors E711 and E712. (Issue #180) * When both a ``tox.ini`` and a ``setup.cfg`` are present in the project directory, merge their contents. The ``tox.ini`` file takes precedence (same as before). (Issue #182) * Give priority to ``--select`` over ``--ignore``. (Issue #188) * Compare full path when excluding a file. (Issue #186) * New option ``--hang-closing`` to switch to the alternative style of closing bracket indentation for hanging indent. Add error E133 for closing bracket which is missing indentation. (Issue #103) * Accept both styles of closing bracket indentation for hanging indent. Do not report error E123 in the default configuration. (Issue #103) Bug fixes: * Do not crash when running AST checks and the document contains null bytes. (Issue #184) * Correctly report other E12 errors when E123 is ignored. (Issue #103) * Fix false positive E261/E262 when the file contains a BOM. (Issue #193) * Fix E701, E702 and E703 not detected sometimes. (Issue #196) * Fix E122 not detected in some cases. (Issue #201 and #208) * Fix false positive E121 with multiple brackets. (Issue #203) 1.4.5 (2013-03-06) ------------------ * When no path is specified, do not try to read from stdin. The feature was added in 1.4.3, but it is not supported on Windows. Use ``-`` filename argument to read from stdin. This usage is supported since 1.3.4. (Issue #170) * Do not require ``setuptools`` in setup.py. It works around an issue with ``pip`` and Python 3. (Issue #172) * Add ``__pycache__`` to the ignore list. * Change misleading message for E251. (Issue #171) * Do not report false E302 when the source file has a coding cookie or a comment on the first line. (Issue #174) * Reorganize the tests and add tests for the API and for the command line usage and options. (Issues #161 and #162) * Ignore all checks which are not explicitly selected when ``select`` is passed to the ``StyleGuide`` constructor. 1.4.4 (2013-02-24) ------------------ * Report E227 or E228 instead of E225 for whitespace around bitwise, shift or modulo operators. (Issue #166) * Change the message for E226 to make clear that it is about arithmetic operators. * Fix a false positive E128 for continuation line indentation with tabs. * Fix regression with the ``--diff`` option. (Issue #169) * Fix the ``TestReport`` class to print the unexpected warnings and errors. 1.4.3 (2013-02-22) ------------------ * Hide the ``--doctest`` and ``--testsuite`` options when installed. * Fix crash with AST checkers when the syntax is invalid. (Issue #160) * Read from standard input if no path is specified. * Initiate a graceful shutdown on ``Control+C``. * Allow changing the ``checker_class`` for the ``StyleGuide``. 1.4.2 (2013-02-10) ------------------ * Support AST checkers provided by third-party applications. * Register new checkers with ``register_check(func_or_cls, codes)``. * Allow constructing a ``StyleGuide`` with a custom parser. * Accept visual indentation without parenthesis after the ``if`` statement. (Issue #151) * Fix UnboundLocalError when using ``# noqa`` with continued lines. (Issue #158) * Re-order the lines for the ``StandardReport``. * Expand tabs when checking E12 continuation lines. (Issue #155) * Refactor the testing class ``TestReport`` and the specific test functions into a separate test module. 1.4.1 (2013-01-18) ------------------ * Allow sphinx.ext.autodoc syntax for comments. (Issue #110) * Report E703 instead of E702 for the trailing semicolon. (Issue #117) * Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149) * Expose the ``OptionParser`` factory for better extensibility. 1.4 (2012-12-22) ---------------- * Report E226 instead of E225 for optional whitespace around common operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error code is ignored in the default configuration because PEP 8 recommends to "use your own judgement". (Issue #96) * Lines with a ``# nopep8`` at the end will not issue errors on line length E501 or continuation line indentation E12*. (Issue #27) * Fix AssertionError when the source file contains an invalid line ending ``"\r\r\n"``. (Issue #119) * Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present. (Issue #93 and #141) * Add the Sphinx-based documentation, and publish it on https://pycodestyle.readthedocs.io/. (Issue #105) 1.3.4 (2012-12-18) ------------------ * Fix false positive E124 and E128 with comments. (Issue #100) * Fix error on stdin when running with bpython. (Issue #101) * Fix false positive E401. (Issue #104) * Report E231 for nested dictionary in list. (Issue #142) * Catch E271 at the beginning of the line. (Issue #133) * Fix false positive E126 for multi-line comments. (Issue #138) * Fix false positive E221 when operator is preceded by a comma. (Issue #135) * Fix ``--diff`` failing on one-line hunk. (Issue #137) * Fix the ``--exclude`` switch for directory paths. (Issue #111) * Use ``-`` filename to read from standard input. (Issue #128) 1.3.3 (2012-06-27) ------------------ * Fix regression with continuation line checker. (Issue #98) 1.3.2 (2012-06-26) ------------------ * Revert to the previous behaviour for ``--show-pep8``: do not imply ``--first``. (Issue #89) * Add E902 for IO errors. (Issue #87) * Fix false positive for E121, and missed E124. (Issue #92) * Set a sensible default path for config file on Windows. (Issue #95) * Allow ``verbose`` in the configuration file. (Issue #91) * Show the enforced ``max-line-length`` in the error message. (Issue #86) 1.3.1 (2012-06-18) ------------------ * Explain which configuration options are expected. Accept and recommend the options names with hyphen instead of underscore. (Issue #82) * Do not read the user configuration when used as a module (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor). * Fix wrong or missing cases for the E12 series. * Fix cases where E122 was missed. (Issue #81) 1.3 (2012-06-15) ---------------- .. warning:: The internal API is backwards incompatible. * Remove global configuration and refactor the library around a ``StyleGuide`` class; add the ability to configure various reporters. (Issue #35 and #66) * Read user configuration from ``~/.config/pep8`` and local configuration from ``./.pep8``. (Issue #22) * Fix E502 for backslash embedded in multi-line string. (Issue #68) * Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72) * Enable the new checkers from the E12 series in the default configuration. * Suggest less error-prone alternatives for E712 errors. * Rewrite checkers to run faster (E22, E251, E27). * Fixed a crash when parsed code is invalid (too many closing brackets). * Fix E127 and E128 for continuation line indentation. (Issue #74) * New option ``--format`` to customize the error format. (Issue #23) * New option ``--diff`` to check only modified code. The unified diff is read from STDIN. Example: ``hg diff | pep8 --diff`` (Issue #39) * Correctly report the count of failures and set the exit code to 1 when the ``--doctest`` or the ``--testsuite`` fails. * Correctly detect the encoding in Python 3. (Issue #69) * Drop support for Python 2.3, 2.4 and 3.0. (Issue #78) 1.2 (2012-06-01) ---------------- * Add E121 through E128 for continuation line indentation. These checks are disabled by default. If you want to force all checks, use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64) * Add E721 for direct type comparisons. (Issue #47) * Add E711 and E712 for comparisons to singletons. (Issue #46) * Fix spurious E225 and E701 for function annotations. (Issue #29) * Add E502 for explicit line join between brackets. * Fix E901 when printing source with ``--show-source``. * Report all errors for each checker, instead of reporting only the first occurrence for each line. * Option ``--show-pep8`` implies ``--first``. 1.1 (2012-05-24) ---------------- * Add E901 for syntax errors. (Issues #63 and #30) * Add E271, E272, E273 and E274 for extraneous whitespace around keywords. (Issue #57) * Add ``tox.ini`` configuration file for tests. (Issue #61) * Add ``.travis.yml`` configuration file for continuous integration. (Issue #62) 1.0.1 (2012-04-06) ------------------ * Fix inconsistent version numbers. 1.0 (2012-04-04) ---------------- * Fix W602 ``raise`` to handle multi-char names. (Issue #53) 0.7.0 (2012-03-26) ------------------ * Now ``--first`` prints only the first occurrence of each error. The ``--repeat`` flag becomes obsolete because it is the default behaviour. (Issue #6) * Allow specifying ``--max-line-length``. (Issue #36) * Make the shebang more flexible. (Issue #26) * Add testsuite to the bundle. (Issue #25) * Fixes for Jython. (Issue #49) * Add PyPI classifiers. (Issue #43) * Fix the ``--exclude`` option. (Issue #48) * Fix W602, accept ``raise`` with 3 arguments. (Issue #34) * Correctly select all tests if ``DEFAULT_IGNORE == ''``. 0.6.1 (2010-10-03) ------------------ * Fix inconsistent version numbers. (Issue #21) 0.6.0 (2010-09-19) ------------------ * Test suite reorganized and enhanced in order to check more failures with fewer test files. Read the ``run_tests`` docstring for details about the syntax. * Fix E225: accept ``print >>sys.stderr, "..."`` syntax. * Fix E501 for lines containing multibyte encoded characters. (Issue #7) * Fix E221, E222, E223, E224 not detected in some cases. (Issue #16) * Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17) * Exit code is always 1 if any error or warning is found. (Issue #10) * ``--ignore`` checks are now really ignored, especially in conjunction with ``--count``. (Issue #8) * Blank lines with spaces yield W293 instead of W291: some developers want to ignore this warning and indent the blank lines to paste their code easily in the Python interpreter. * Fix E301: do not require a blank line before an indented block. (Issue #14) * Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13) * Performance improvements. * Fix decoding and checking non-UTF8 files in Python 3. * Fix E225: reject ``True+False`` when running on Python 3. * Fix an exception when the line starts with an operator. * Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5) 0.5.0 (2010-02-17) ------------------ * Changed the ``--count`` switch to print to sys.stderr and set exit code to 1 if any error or warning is found. * E241 and E242 are removed from the standard checks. If you want to include these checks, use switch ``--select=E,W``. (Issue #4) * Blank line is not mandatory before the first class method or nested function definition, even if there's a docstring. (Issue #1) * Add the switch ``--version``. * Fix decoding errors with Python 3. (Issue #13 [1]_) * Add ``--select`` option which is mirror of ``--ignore``. * Add checks E261 and E262 for spaces before inline comments. * New check W604 warns about deprecated usage of backticks. * New check W603 warns about the deprecated operator ``<>``. * Performance improvement, due to rewriting of E225. * E225 now accepts: - no whitespace after unary operator or similar. (Issue #9 [1]_) - lambda function with argument unpacking or keyword defaults. * Reserve "2 blank lines" for module-level logical blocks. (E303) * Allow multi-line comments. (E302, issue #10 [1]_) 0.4.2 (2009-10-22) ------------------ * Decorators on classes and class methods are OK now. 0.4 (2009-10-20) ---------------- * Support for all versions of Python from 2.3 to 3.1. * New and greatly expanded self tests. * Added ``--count`` option to print the total number of errors and warnings. * Further improvements to the handling of comments and blank lines. (Issue #1 [1]_ and others changes.) * Check all py files in directory when passed a directory (Issue #2 [1]_). This also prevents an exception when traversing directories with non ``*.py`` files. * E231 should allow commas to be followed by ``)``. (Issue #3 [1]_) * Spaces are no longer required around the equals sign for keyword arguments or default parameter values. .. [1] These issues refer to the `previous issue tracker`__. .. __: http://github.com/cburroughs/pep8.py/issues 0.3.1 (2009-09-14) ------------------ * Fixes for comments: do not count them when checking for blank lines between items. * Added setup.py for pypi upload and easy_installability. 0.2 (2007-10-16) ---------------- * Loads of fixes and improvements. 0.1 (2006-10-01) ---------------- * First release. Keywords: pycodestyle,pep8,PEP 8,PEP-8,PEP8 Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* pycodestyle-2.5.0/pycodestyle.egg-info/top_level.txt0000664000175000017500000000001413424056203024246 0ustar icordascicordasc00000000000000pycodestyle pycodestyle-2.5.0/pycodestyle.egg-info/not-zip-safe0000664000175000017500000000000113042370027023746 0ustar icordascicordasc00000000000000 pycodestyle-2.5.0/CONTRIBUTING.rst0000664000175000017500000000575313424054446020145 0ustar icordascicordasc00000000000000Contributing to pycodestyle =========================== When contributing to pycodestyle, please observe our `Code of Conduct`_. Step 1: Forking pycodestyle for editing --------------------------------------- Fork the pycodestyle repository on GitHub. This will add pycodestyle to your GitHub account. You will push your changes to your fork and then make pull requests into the official pycodestyle repository. GitHub has an excellent `guide`_ that has screenshots on how to do this. Next, clone your fork of the pycodestyle repository to your system for editing:: $ git clone https://www.github.com//pycodestyle Now you have a copy of the pycodestyle codebase that is almost ready for edits. Next we will setup `virtualenv`_ which will help create an isolated environment to manage dependencies. Step 2: Use virtualenv when developing -------------------------------------- `virtualenv`_ is a tool to create isolated python environments. First, install virtualenv with:: $ pip install virtualenv Next, ``cd`` to the pycodestyle repository that you cloned earlier and create, then activate a virtualenv:: $ cd pycodestyle $ virtualenv pycodestyle-venv $ source pycodestyle-venv/bin/activate Now you can install the pycodestyle requirements:: $ pip install -r dev-requirements.txt To deactivate the virtualenv you can type:: $ deactivate For more information see `virtualenv`_'s documentation. Step 3: Run tests ----------------- Before creating a pull request you should run the tests to make sure that the changes that have been made haven't caused any regressions in functionality. To run the tests, the core developer team and Travis-CI use `tox`_:: $ pip install -r dev-requirements.txt $ tox All the tests should pass for all available interpreters, with the summary of:: congratulations :) At this point you can create a pull request back to the official pycodestyle repository for review! For more information on how to make a pull request, GitHub has an excellent `guide`_. The current tests are written in 2 styles: * standard xUnit based only on stdlib unittest * functional test using a custom framework and executed by the pycodestyle itself when installed in dev mode. Running unittest ~~~~~~~~~~~~~~~~ The tests are written using stdlib ``unittest`` module, the existing tests include unit, integration and functional tests. To run the tests:: $ python setup.py test Running functional ~~~~~~~~~~~~~~~~~~ When installed in dev mode, pycodestyle will have the ``--testsuite`` option which can be used to run the tests:: $ pip install -e . $ # Run all tests. $ pycodestyle --testsuite testsuite $ # Run a subset of the tests. $ pycodestyle --testsuite testsuite/E30.py .. _virtualenv: http://docs.python-guide.org/en/latest/dev/virtualenvs/ .. _guide: https://guides.github.com/activities/forking/ .. _tox: https://tox.readthedocs.io/en/latest/ .. _Code of Conduct: http://meta.pycqa.org/en/latest/code-of-conduct.html pycodestyle-2.5.0/PKG-INFO0000664000175000017500000010724713424056203016573 0ustar icordascicordasc00000000000000Metadata-Version: 1.2 Name: pycodestyle Version: 2.5.0 Summary: Python style guide checker Home-page: https://pycodestyle.readthedocs.io/ Author: Ian Lee Author-email: IanLee1521@gmail.com License: Expat license Description-Content-Type: UNKNOWN Description: pycodestyle (formerly called pep8) - Python style guide checker =============================================================== .. image:: https://img.shields.io/travis/PyCQA/pycodestyle.svg :target: https://travis-ci.org/PyCQA/pycodestyle :alt: Build status .. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest :target: https://pycodestyle.readthedocs.io :alt: Documentation Status .. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg :target: https://pypi.org/project/pycodestyle/ :alt: Wheel Status .. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge pycodestyle is a tool to check your Python code against some of the style conventions in `PEP 8`_. .. _PEP 8: http://www.python.org/dev/peps/pep-0008/ .. note:: This package used to be called ``pep8`` but was renamed to ``pycodestyle`` to reduce confusion. Further discussion can be found `in the issue where Guido requested this change `_, or in the lightning talk at PyCon 2016 by @IanLee1521: `slides `_ `video `_. Features -------- * Plugin architecture: Adding new checks is easy. * Parseable output: Jump to error location in your editor. * Small: Just one Python file, requires only stdlib. You can use just the ``pycodestyle.py`` file for this purpose. * Comes with a comprehensive test suite. Installation ------------ You can install, upgrade, and uninstall ``pycodestyle.py`` with these commands:: $ pip install pycodestyle $ pip install --upgrade pycodestyle $ pip uninstall pycodestyle There's also a package for Debian/Ubuntu, but it's not always the latest version. Example usage and output ------------------------ :: $ pycodestyle --first optparse.py optparse.py:69:11: E401 multiple imports on one line optparse.py:77:1: E302 expected 2 blank lines, found 1 optparse.py:88:5: E301 expected 1 blank line, found 0 optparse.py:222:34: W602 deprecated form of raising exception optparse.py:347:31: E211 whitespace before '(' optparse.py:357:17: E201 whitespace after '{' optparse.py:472:29: E221 multiple spaces before operator optparse.py:544:21: W601 .has_key() is deprecated, use 'in' You can also make ``pycodestyle.py`` show the source code for each error, and even the relevant text from PEP 8:: $ pycodestyle --show-source --show-pep8 testsuite/E40.py testsuite/E40.py:2:10: E401 multiple imports on one line import os, sys ^ Imports should usually be on separate lines. Okay: import os\nimport sys E401: import sys, os Or you can display how often each error was found:: $ pycodestyle --statistics -qq Python-2.5/Lib 232 E201 whitespace after '[' 599 E202 whitespace before ')' 631 E203 whitespace before ',' 842 E211 whitespace before '(' 2531 E221 multiple spaces before operator 4473 E301 expected 1 blank line, found 0 4006 E302 expected 2 blank lines, found 1 165 E303 too many blank lines (4) 325 E401 multiple imports on one line 3615 E501 line too long (82 characters) 612 W601 .has_key() is deprecated, use 'in' 1188 W602 deprecated form of raising exception Links ----- * `Read the documentation `_ * `Fork me on GitHub `_ Changelog ========= 2.5.0 (2019-01-29) ------------------ New checks: * E117: Over-indented code blocks * W505: Maximum doc-string length only when configured with --max-doc-length Changes: * Remove support for EOL Python 2.6 and 3.3. PR #720. * Add E117 error for over-indented code blocks. * Allow W605 to be silenced by `# noqa` and fix the position reported by W605 * Allow users to omit blank lines around one-liner definitions of classes and functions * Include the function return annotation (``->``) as requiring surrounding whitespace only on Python 3 * Verify that only names can follow ``await``. Previously we allowed numbers and strings. * Add support for Python 3.7 * Fix detection of annotated argument defaults for E252 * Cprrect the position reported by W504 2.4.0 (2018-04-10) ------------------ New checks: * Add W504 warning for checking that a break doesn't happen after a binary operator. This check is ignored by default. PR #502. * Add W605 warning for invalid escape sequences in string literals. PR #676. * Add W606 warning for 'async' and 'await' reserved keywords being introduced in Python 3.7. PR #684. * Add E252 error for missing whitespace around equal sign in type annotated function arguments with defaults values. PR #717. Changes: * An internal bisect search has replaced a linear search in order to improve efficiency. PR #648. * pycodestyle now uses PyPI trove classifiers in order to document supported python versions on PyPI. PR #654. * 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as the former is legacy. PR #653. * pycodestyle now handles very long lines much more efficiently for python 3.2+. Fixes #643. PR #644. * You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve verbosity. PR #663. * The distribution of pycodestyle now includes the license text in order to comply with open source licenses which require this. PR #694. * 'maximum_line_length' now ignores shebang ('#!') lines. PR #736. * Add configuration option for the allowed number of blank lines. It is implemented as a top level dictionary which can be easily overwritten. Fixes #732. PR #733. Bugs: * Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused by an invalid escape sequence. PR #625. * Correctly report E501 when the first line of a docstring is too long. Resolves #622. PR #630. * Support variable annotation when variable start by a keyword, such as class variable type annotations in python 3.6. PR #640. * pycodestyle internals have been changed in order to allow 'python3 -m cProfile' to report correct metrics. PR #647. * Fix a spelling mistake in the description of E722. PR #697. * 'pycodestyle --diff' now does not break if your 'gitconfig' enables 'mnemonicprefix'. PR #706. 2.3.1 (2017-01-31) ------------------ Bugs: * Fix regression in detection of E302 and E306; #618, #620 2.3.0 (2017-01-30) ------------------ New Checks: * Add E722 warning for bare ``except`` clauses * Report E704 for async function definitions (``async def``) Bugs: * Fix another E305 false positive for variables beginning with "class" or "def" * Fix detection of multiple spaces between ``async`` and ``def`` * Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for variable annotations. 2.2.0 (2016-11-14) ------------------ Announcements: * Added Make target to obtain proper tarball file permissions; #599 Bugs: * Fixed E305 regression caused by #400; #593 2.1.0 (2016-11-04) ------------------ Announcements: * Change all references to the pep8 project to say pycodestyle; #530 Changes: * Report E302 for blank lines before an "async def"; #556 * Update our list of tested and supported Python versions which are 2.6, 2.7, 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy. * Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'. * Report E741 on 'global' and 'nonlocal' statements, as well as prohibited single-letter variables. * Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591 * Report E722 when bare except clause is used; #579 Bugs: * Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561 * Require two blank lines after toplevel def, class; #536 * Remove accidentally quadratic computation based on the number of colons. This will make pycodestyle faster in some cases; #314 2.0.0 (2016-05-31) ------------------ Announcements: * Repository renamed to `pycodestyle`; Issue #466 / #481. * Added joint Code of Conduct as member of PyCQA; #483 Changes: * Added tox test support for Python 3.5 and pypy3 * Added check E275 for whitespace on `from ... import ...` lines; #489 / #491 * Added W503 to the list of codes ignored by default ignore list; #498 * Removed use of project level `.pep8` configuration file; #364 Bugs: * Fixed bug with treating `~` operator as binary; #383 / #384 * Identify binary operators as unary; #484 / #485 1.7.0 (2016-01-12) ------------------ Announcements: * Repository moved to PyCQA Organization on GitHub: https://github.com/pycqa/pep8 Changes: * Reverted the fix in #368, "options passed on command line are only ones accepted" feature. This has many unintended consequences in pep8 and flake8 and needs to be reworked when I have more time. * Added support for Python 3.5. (Issue #420 & #459) * Added support for multi-line config_file option parsing. (Issue #429) * Improved parameter parsing. (Issues #420 & #456) Bugs: * Fixed BytesWarning on Python 3. (Issue #459) 1.6.2 (2015-02-15) ------------------ Changes: * Added check for breaking around a binary operator. (Issue #197, Pull #305) Bugs: * Restored config_file parameter in process_options(). (Issue #380) 1.6.1 (2015-02-08) ------------------ Changes: * Assign variables before referenced. (Issue #287) Bugs: * Exception thrown due to unassigned ``local_dir`` variable. (Issue #377) 1.6.0 (2015-02-06) ------------------ News: * Ian Lee joined the project as a maintainer. Changes: * Report E731 for lambda assignment. (Issue #277) * Report E704 for one-liner def instead of E701. Do not report this error in the default configuration. (Issue #277) * Replace codes E111, E112 and E113 with codes E114, E115 and E116 for bad indentation of comments. (Issue #274) * Report E266 instead of E265 when the block comment starts with multiple ``#``. (Issue #270) * Report E402 for import statements not at the top of the file. (Issue #264) * Do not enforce whitespaces around ``**`` operator. (Issue #292) * Strip whitespace from around paths during normalization. (Issue #339 / #343) * Update ``--format`` documentation. (Issue #198 / Pull Request #310) * Add ``.tox/`` to default excludes. (Issue #335) * Do not report E121 or E126 in the default configuration. (Issues #256 / #316) * Allow spaces around the equals sign in an annotated function. (Issue #357) * Allow trailing backslash if in an inline comment. (Issue #374) * If ``--config`` is used, only that configuration is processed. Otherwise, merge the user and local configurations are merged. (Issue #368 / #369) Bug fixes: * Don't crash if Checker.build_tokens_line() returns None. (Issue #306) * Don't crash if os.path.expanduser() throws an ImportError. (Issue #297) * Missing space around keyword parameter equal not always reported, E251. (Issue #323) * Fix false positive E711/E712/E713. (Issues #330 and #336) * Do not skip physical checks if the newline is escaped. (Issue #319) * Flush sys.stdout to avoid race conditions with printing. See flake8 bug: https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363) 1.5.7 (2014-05-29) ------------------ Bug fixes: * Skip the traceback on "Broken pipe" signal. (Issue #275) * Do not exit when an option in ``setup.cfg`` or ``tox.ini`` is not recognized. * Check the last line even if it does not end with a newline. (Issue #286) * Always open files in universal newlines mode in Python 2. (Issue #288) 1.5.6 (2014-04-14) ------------------ Bug fixes: * Check the last line even if it has no end-of-line. (Issue #273) 1.5.5 (2014-04-10) ------------------ Bug fixes: * Fix regression with E22 checks and inline comments. (Issue #271) 1.5.4 (2014-04-07) ------------------ Bug fixes: * Fix negative offset with E303 before a multi-line docstring. (Issue #269) 1.5.3 (2014-04-04) ------------------ Bug fixes: * Fix wrong offset computation when error is on the last char of a physical line. (Issue #268) 1.5.2 (2014-04-04) ------------------ Changes: * Distribute a universal wheel file. Bug fixes: * Report correct line number for E303 with comments. (Issue #60) * Do not allow newline after parameter equal. (Issue #252) * Fix line number reported for multi-line strings. (Issue #220) * Fix false positive E121/E126 with multi-line strings. (Issue #265) * Fix E501 not detected in comments with Python 2.5. * Fix caret position with ``--show-source`` when line contains tabs. 1.5.1 (2014-03-27) ------------------ Bug fixes: * Fix a crash with E125 on multi-line strings. (Issue #263) 1.5 (2014-03-26) ---------------- Changes: * Report E129 instead of E125 for visually indented line with same indent as next logical line. (Issue #126) * Report E265 for space before block comment. (Issue #190) * Report E713 and E714 when operators ``not in`` and ``is not`` are recommended. (Issue #236) * Allow long lines in multiline strings and comments if they cannot be wrapped. (Issue #224). * Optionally disable physical line checks inside multiline strings, using ``# noqa``. (Issue #242) * Change text for E121 to report "continuation line under-indented for hanging indent" instead of indentation not being a multiple of 4. * Report E131 instead of E121 / E126 if the hanging indent is not consistent within the same continuation block. It helps when error E121 or E126 is in the ``ignore`` list. * Report E126 instead of E121 when the continuation line is hanging with extra indentation, even if indentation is not a multiple of 4. Bug fixes: * Allow the checkers to report errors on empty files. (Issue #240) * Fix ignoring too many checks when ``--select`` is used with codes declared in a flake8 extension. (Issue #216) * Fix regression with multiple brackets. (Issue #214) * Fix ``StyleGuide`` to parse the local configuration if the keyword argument ``paths`` is specified. (Issue #246) * Fix a false positive E124 for hanging indent. (Issue #254) * Fix a false positive E126 with embedded colon. (Issue #144) * Fix a false positive E126 when indenting with tabs. (Issue #204) * Fix behaviour when ``exclude`` is in the configuration file and the current directory is not the project directory. (Issue #247) * The logical checks can return ``None`` instead of an empty iterator. (Issue #250) * Do not report multiple E101 if only the first indentation starts with a tab. (Issue #237) * Fix a rare false positive W602. (Issue #34) 1.4.6 (2013-07-02) ------------------ Changes: * Honor ``# noqa`` for errors E711 and E712. (Issue #180) * When both a ``tox.ini`` and a ``setup.cfg`` are present in the project directory, merge their contents. The ``tox.ini`` file takes precedence (same as before). (Issue #182) * Give priority to ``--select`` over ``--ignore``. (Issue #188) * Compare full path when excluding a file. (Issue #186) * New option ``--hang-closing`` to switch to the alternative style of closing bracket indentation for hanging indent. Add error E133 for closing bracket which is missing indentation. (Issue #103) * Accept both styles of closing bracket indentation for hanging indent. Do not report error E123 in the default configuration. (Issue #103) Bug fixes: * Do not crash when running AST checks and the document contains null bytes. (Issue #184) * Correctly report other E12 errors when E123 is ignored. (Issue #103) * Fix false positive E261/E262 when the file contains a BOM. (Issue #193) * Fix E701, E702 and E703 not detected sometimes. (Issue #196) * Fix E122 not detected in some cases. (Issue #201 and #208) * Fix false positive E121 with multiple brackets. (Issue #203) 1.4.5 (2013-03-06) ------------------ * When no path is specified, do not try to read from stdin. The feature was added in 1.4.3, but it is not supported on Windows. Use ``-`` filename argument to read from stdin. This usage is supported since 1.3.4. (Issue #170) * Do not require ``setuptools`` in setup.py. It works around an issue with ``pip`` and Python 3. (Issue #172) * Add ``__pycache__`` to the ignore list. * Change misleading message for E251. (Issue #171) * Do not report false E302 when the source file has a coding cookie or a comment on the first line. (Issue #174) * Reorganize the tests and add tests for the API and for the command line usage and options. (Issues #161 and #162) * Ignore all checks which are not explicitly selected when ``select`` is passed to the ``StyleGuide`` constructor. 1.4.4 (2013-02-24) ------------------ * Report E227 or E228 instead of E225 for whitespace around bitwise, shift or modulo operators. (Issue #166) * Change the message for E226 to make clear that it is about arithmetic operators. * Fix a false positive E128 for continuation line indentation with tabs. * Fix regression with the ``--diff`` option. (Issue #169) * Fix the ``TestReport`` class to print the unexpected warnings and errors. 1.4.3 (2013-02-22) ------------------ * Hide the ``--doctest`` and ``--testsuite`` options when installed. * Fix crash with AST checkers when the syntax is invalid. (Issue #160) * Read from standard input if no path is specified. * Initiate a graceful shutdown on ``Control+C``. * Allow changing the ``checker_class`` for the ``StyleGuide``. 1.4.2 (2013-02-10) ------------------ * Support AST checkers provided by third-party applications. * Register new checkers with ``register_check(func_or_cls, codes)``. * Allow constructing a ``StyleGuide`` with a custom parser. * Accept visual indentation without parenthesis after the ``if`` statement. (Issue #151) * Fix UnboundLocalError when using ``# noqa`` with continued lines. (Issue #158) * Re-order the lines for the ``StandardReport``. * Expand tabs when checking E12 continuation lines. (Issue #155) * Refactor the testing class ``TestReport`` and the specific test functions into a separate test module. 1.4.1 (2013-01-18) ------------------ * Allow sphinx.ext.autodoc syntax for comments. (Issue #110) * Report E703 instead of E702 for the trailing semicolon. (Issue #117) * Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149) * Expose the ``OptionParser`` factory for better extensibility. 1.4 (2012-12-22) ---------------- * Report E226 instead of E225 for optional whitespace around common operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error code is ignored in the default configuration because PEP 8 recommends to "use your own judgement". (Issue #96) * Lines with a ``# nopep8`` at the end will not issue errors on line length E501 or continuation line indentation E12*. (Issue #27) * Fix AssertionError when the source file contains an invalid line ending ``"\r\r\n"``. (Issue #119) * Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present. (Issue #93 and #141) * Add the Sphinx-based documentation, and publish it on https://pycodestyle.readthedocs.io/. (Issue #105) 1.3.4 (2012-12-18) ------------------ * Fix false positive E124 and E128 with comments. (Issue #100) * Fix error on stdin when running with bpython. (Issue #101) * Fix false positive E401. (Issue #104) * Report E231 for nested dictionary in list. (Issue #142) * Catch E271 at the beginning of the line. (Issue #133) * Fix false positive E126 for multi-line comments. (Issue #138) * Fix false positive E221 when operator is preceded by a comma. (Issue #135) * Fix ``--diff`` failing on one-line hunk. (Issue #137) * Fix the ``--exclude`` switch for directory paths. (Issue #111) * Use ``-`` filename to read from standard input. (Issue #128) 1.3.3 (2012-06-27) ------------------ * Fix regression with continuation line checker. (Issue #98) 1.3.2 (2012-06-26) ------------------ * Revert to the previous behaviour for ``--show-pep8``: do not imply ``--first``. (Issue #89) * Add E902 for IO errors. (Issue #87) * Fix false positive for E121, and missed E124. (Issue #92) * Set a sensible default path for config file on Windows. (Issue #95) * Allow ``verbose`` in the configuration file. (Issue #91) * Show the enforced ``max-line-length`` in the error message. (Issue #86) 1.3.1 (2012-06-18) ------------------ * Explain which configuration options are expected. Accept and recommend the options names with hyphen instead of underscore. (Issue #82) * Do not read the user configuration when used as a module (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor). * Fix wrong or missing cases for the E12 series. * Fix cases where E122 was missed. (Issue #81) 1.3 (2012-06-15) ---------------- .. warning:: The internal API is backwards incompatible. * Remove global configuration and refactor the library around a ``StyleGuide`` class; add the ability to configure various reporters. (Issue #35 and #66) * Read user configuration from ``~/.config/pep8`` and local configuration from ``./.pep8``. (Issue #22) * Fix E502 for backslash embedded in multi-line string. (Issue #68) * Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72) * Enable the new checkers from the E12 series in the default configuration. * Suggest less error-prone alternatives for E712 errors. * Rewrite checkers to run faster (E22, E251, E27). * Fixed a crash when parsed code is invalid (too many closing brackets). * Fix E127 and E128 for continuation line indentation. (Issue #74) * New option ``--format`` to customize the error format. (Issue #23) * New option ``--diff`` to check only modified code. The unified diff is read from STDIN. Example: ``hg diff | pep8 --diff`` (Issue #39) * Correctly report the count of failures and set the exit code to 1 when the ``--doctest`` or the ``--testsuite`` fails. * Correctly detect the encoding in Python 3. (Issue #69) * Drop support for Python 2.3, 2.4 and 3.0. (Issue #78) 1.2 (2012-06-01) ---------------- * Add E121 through E128 for continuation line indentation. These checks are disabled by default. If you want to force all checks, use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64) * Add E721 for direct type comparisons. (Issue #47) * Add E711 and E712 for comparisons to singletons. (Issue #46) * Fix spurious E225 and E701 for function annotations. (Issue #29) * Add E502 for explicit line join between brackets. * Fix E901 when printing source with ``--show-source``. * Report all errors for each checker, instead of reporting only the first occurrence for each line. * Option ``--show-pep8`` implies ``--first``. 1.1 (2012-05-24) ---------------- * Add E901 for syntax errors. (Issues #63 and #30) * Add E271, E272, E273 and E274 for extraneous whitespace around keywords. (Issue #57) * Add ``tox.ini`` configuration file for tests. (Issue #61) * Add ``.travis.yml`` configuration file for continuous integration. (Issue #62) 1.0.1 (2012-04-06) ------------------ * Fix inconsistent version numbers. 1.0 (2012-04-04) ---------------- * Fix W602 ``raise`` to handle multi-char names. (Issue #53) 0.7.0 (2012-03-26) ------------------ * Now ``--first`` prints only the first occurrence of each error. The ``--repeat`` flag becomes obsolete because it is the default behaviour. (Issue #6) * Allow specifying ``--max-line-length``. (Issue #36) * Make the shebang more flexible. (Issue #26) * Add testsuite to the bundle. (Issue #25) * Fixes for Jython. (Issue #49) * Add PyPI classifiers. (Issue #43) * Fix the ``--exclude`` option. (Issue #48) * Fix W602, accept ``raise`` with 3 arguments. (Issue #34) * Correctly select all tests if ``DEFAULT_IGNORE == ''``. 0.6.1 (2010-10-03) ------------------ * Fix inconsistent version numbers. (Issue #21) 0.6.0 (2010-09-19) ------------------ * Test suite reorganized and enhanced in order to check more failures with fewer test files. Read the ``run_tests`` docstring for details about the syntax. * Fix E225: accept ``print >>sys.stderr, "..."`` syntax. * Fix E501 for lines containing multibyte encoded characters. (Issue #7) * Fix E221, E222, E223, E224 not detected in some cases. (Issue #16) * Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17) * Exit code is always 1 if any error or warning is found. (Issue #10) * ``--ignore`` checks are now really ignored, especially in conjunction with ``--count``. (Issue #8) * Blank lines with spaces yield W293 instead of W291: some developers want to ignore this warning and indent the blank lines to paste their code easily in the Python interpreter. * Fix E301: do not require a blank line before an indented block. (Issue #14) * Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13) * Performance improvements. * Fix decoding and checking non-UTF8 files in Python 3. * Fix E225: reject ``True+False`` when running on Python 3. * Fix an exception when the line starts with an operator. * Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5) 0.5.0 (2010-02-17) ------------------ * Changed the ``--count`` switch to print to sys.stderr and set exit code to 1 if any error or warning is found. * E241 and E242 are removed from the standard checks. If you want to include these checks, use switch ``--select=E,W``. (Issue #4) * Blank line is not mandatory before the first class method or nested function definition, even if there's a docstring. (Issue #1) * Add the switch ``--version``. * Fix decoding errors with Python 3. (Issue #13 [1]_) * Add ``--select`` option which is mirror of ``--ignore``. * Add checks E261 and E262 for spaces before inline comments. * New check W604 warns about deprecated usage of backticks. * New check W603 warns about the deprecated operator ``<>``. * Performance improvement, due to rewriting of E225. * E225 now accepts: - no whitespace after unary operator or similar. (Issue #9 [1]_) - lambda function with argument unpacking or keyword defaults. * Reserve "2 blank lines" for module-level logical blocks. (E303) * Allow multi-line comments. (E302, issue #10 [1]_) 0.4.2 (2009-10-22) ------------------ * Decorators on classes and class methods are OK now. 0.4 (2009-10-20) ---------------- * Support for all versions of Python from 2.3 to 3.1. * New and greatly expanded self tests. * Added ``--count`` option to print the total number of errors and warnings. * Further improvements to the handling of comments and blank lines. (Issue #1 [1]_ and others changes.) * Check all py files in directory when passed a directory (Issue #2 [1]_). This also prevents an exception when traversing directories with non ``*.py`` files. * E231 should allow commas to be followed by ``)``. (Issue #3 [1]_) * Spaces are no longer required around the equals sign for keyword arguments or default parameter values. .. [1] These issues refer to the `previous issue tracker`__. .. __: http://github.com/cburroughs/pep8.py/issues 0.3.1 (2009-09-14) ------------------ * Fixes for comments: do not count them when checking for blank lines between items. * Added setup.py for pypi upload and easy_installability. 0.2 (2007-10-16) ---------------- * Loads of fixes and improvements. 0.1 (2006-10-01) ---------------- * First release. Keywords: pycodestyle,pep8,PEP 8,PEP-8,PEP8 Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* pycodestyle-2.5.0/docs/0000775000175000017500000000000013424056203016413 5ustar icordascicordasc00000000000000pycodestyle-2.5.0/docs/developer.rst0000664000175000017500000001021213424054446021135 0ustar icordascicordasc00000000000000.. currentmodule:: pycodestyle ================= Developer's notes ================= Source code ~~~~~~~~~~~ The source code is currently `available on GitHub`_ under the terms and conditions of the :ref:`Expat license `. Fork away! * `Source code `_ and `issue tracker `_ on GitHub. * `Continuous tests `_ against Python 2.7 and 3.4+ as well as the nightly Python build and PyPy, on `Travis CI platform `_. .. _available on GitHub: https://github.com/pycqa/pycodestyle Direction ~~~~~~~~~ Some high-level aims and directions to bear in mind for contributions: * ``pycodestyle`` is intended to be as fast as possible. Using the ``ast`` module defeats that purpose. The `pep8-naming `_ plugin exists for this sort of functionality. * If you want to provide extensibility / plugins, please see `flake8 `_ - ``pycodestyle`` doesn't want or need a plugin architecture. * ``pycodestyle`` aims to have no external dependencies. Contribute ~~~~~~~~~~ You can add checks to this program by writing plugins. Each plugin is a simple function that is called for each line of source code, either physical or logical. Physical line: * Raw line of text from the input file. Logical line: * Multi-line statements converted to a single line. * Stripped left and right. * Contents of strings replaced with ``"xxx"`` of same length. * Comments removed. The check function requests physical or logical lines by the name of the first argument:: def maximum_line_length(physical_line) def extraneous_whitespace(logical_line) def blank_lines(logical_line, blank_lines, indent_level, line_number) The last example above demonstrates how check plugins can request additional information with extra arguments. All attributes of the :class:`Checker` object are available. Some examples: * ``lines``: a list of the raw lines from the input file * ``tokens``: the tokens that contribute to this logical line * ``line_number``: line number in the input file * ``total_lines``: number of lines in the input file * ``blank_lines``: blank lines before this one * ``indent_char``: indentation character in this file (``" "`` or ``"\t"``) * ``indent_level``: indentation (with tabs expanded to multiples of 8) * ``previous_indent_level``: indentation on previous line * ``previous_logical``: previous logical line Check plugins can also maintain per-file state. If you need this, declare a parameter named ``checker_state``. You will be passed a dict, which will be the same one for all lines in the same file but a different one for different files. Each check plugin gets its own dict, so you don't need to worry about clobbering the state of other plugins. The docstring of each check function shall be the relevant part of text from `PEP 8`_. It is printed if the user enables ``--show-pep8``. Several docstrings contain examples directly from the `PEP 8`_ document. :: Okay: spam(ham[1], {eggs: 2}) E201: spam( ham[1], {eggs: 2}) These examples are verified automatically when ``pycodestyle.py`` is run with the ``--doctest`` option. You can add examples for your own check functions. The format is simple: ``"Okay"`` or error/warning code followed by colon and space, the rest of the line is example source code. If you put ``'r'`` before the docstring, you can use ``\n`` for newline and ``\t`` for tab. Then be sure to pass the tests:: $ python pycodestyle.py --testsuite testsuite $ python pycodestyle.py --doctest $ python pycodestyle.py --verbose pycodestyle.py When contributing to pycodestyle, please observe our `Code of Conduct`_. To run the tests, the core developer team and Travis CI use tox:: $ pip install -r dev-requirements.txt $ tox All the tests should pass for all available interpreters, with the summary of:: congratulations :) .. _PEP 8: http://www.python.org/dev/peps/pep-0008/ .. _Code of Conduct: http://meta.pycqa.org/en/latest/code-of-conduct.html Changes ~~~~~~~ .. include:: ../CHANGES.txt :start-line: 3 pycodestyle-2.5.0/docs/conf.py0000664000175000017500000002021013230006455017704 0ustar icordascicordasc00000000000000# -*- coding: utf-8 -*- # # pycodestyle documentation build configuration file, created by # sphinx-quickstart on Tue Aug 21 09:47:49 2012. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) sys.path.insert(0, os.path.abspath('..')) # -- General configuration ---------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage', 'sphinx.ext.viewcode'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'pycodestyle' authors = u'Johann C. Rocholl, Florent Xicluna, Ian Lee' copyright = u'2006-2016, %s' % (authors) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # pkg_version = __import__('pycodestyle').__version__.split('.') # The short X.Y version. version = '.'.join(pkg_version[:2]) # The full version, including alpha/beta/rc tags. release = '.'.join(pkg_version) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for # all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output -------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if not on_rtd: # only import and set the theme if we're building docs locally import sphinx_rtd_theme html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". # html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'pycodestyledoc' # -- Options for LaTeX output ------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto/manual]). latex_documents = [ ('index', 'pycodestyle.tex', u'pycodestyle documentation', authors, 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output ------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'pycodestyle', u'pycodestyle documentation', [authors], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ----------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'pycodestyle', u'pycodestyle documentation', authors, 'pycodestyle', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' pycodestyle-2.5.0/docs/intro.rst0000664000175000017500000006514113424054446020316 0ustar icordascicordasc00000000000000.. currentmodule:: pycodestyle Introduction ============ pycodestyle is a tool to check your Python code against some of the style conventions in `PEP 8`_. .. contents:: :local: Features -------- * Plugin architecture: Adding new checks is easy. * Parseable output: Jump to error location in your editor. * Small: Just one Python file, requires only stdlib. You can use just the ``pycodestyle.py`` file for this purpose. * Comes with a comprehensive test suite. Disclaimer ---------- This utility does not enforce every single rule of PEP 8. It helps to verify that some coding conventions are applied but it does not intend to be exhaustive. Some rules cannot be expressed with a simple algorithm, and other rules are only guidelines which you could circumvent when you need to. Always remember this statement from `PEP 8`_: *A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is most important.* Among other things, these features are currently not in the scope of the ``pycodestyle`` library: * **naming conventions**: this kind of feature is supported through plugins. Install `flake8 `_ and the `pep8-naming extension `_ to use this feature. * **docstring conventions**: they are not in the scope of this library; see the `pydocstyle project `_. * **automatic fixing**: see the section *PEP8 Fixers* in the :ref:`related tools ` page. Installation ------------ You can install, upgrade, uninstall ``pycodestyle.py`` with these commands:: $ pip install pycodestyle $ pip install --upgrade pycodestyle $ pip uninstall pycodestyle Example usage and output ------------------------ :: $ pycodestyle --first optparse.py optparse.py:69:11: E401 multiple imports on one line optparse.py:77:1: E302 expected 2 blank lines, found 1 optparse.py:88:5: E301 expected 1 blank line, found 0 optparse.py:222:34: W602 deprecated form of raising exception optparse.py:347:31: E211 whitespace before '(' optparse.py:357:17: E201 whitespace after '{' optparse.py:472:29: E221 multiple spaces before operator optparse.py:544:21: W601 .has_key() is deprecated, use 'in' You can also make ``pycodestyle.py`` show the source code for each error, and even the relevant text from PEP 8:: $ pycodestyle --show-source --show-pep8 testsuite/E40.py testsuite/E40.py:2:10: E401 multiple imports on one line import os, sys ^ Imports should usually be on separate lines. Okay: import os\nimport sys E401: import sys, os Or you can display how often each error was found:: $ pycodestyle --statistics -qq Python-2.5/Lib 232 E201 whitespace after '[' 599 E202 whitespace before ')' 631 E203 whitespace before ',' 842 E211 whitespace before '(' 2531 E221 multiple spaces before operator 4473 E301 expected 1 blank line, found 0 4006 E302 expected 2 blank lines, found 1 165 E303 too many blank lines (4) 325 E401 multiple imports on one line 3615 E501 line too long (82 characters) 612 W601 .has_key() is deprecated, use 'in' 1188 W602 deprecated form of raising exception You can also make ``pycodestyle.py`` show the error text in different formats by using ``--format`` having options default/pylint/custom:: $ pycodestyle testsuite/E40.py --format=default testsuite/E40.py:2:10: E401 multiple imports on one line $ pycodestyle testsuite/E40.py --format=pylint testsuite/E40.py:2: [E401] multiple imports on one line $ pycodestyle testsuite/E40.py --format='%(path)s|%(row)d|%(col)d| %(code)s %(text)s' testsuite/E40.py|2|10| E401 multiple imports on one line Variables in the ``custom`` format option +----------------+------------------+ | Variable | Significance | +================+==================+ | ``path`` | File name | +----------------+------------------+ | ``row`` | Row number | +----------------+------------------+ | ``col`` | Column number | +----------------+------------------+ | ``code`` | Error code | +----------------+------------------+ | ``text`` | Error text | +----------------+------------------+ Quick help is available on the command line:: $ pycodestyle -h Usage: pycodestyle [options] input ... Options: --version show program's version number and exit -h, --help show this help message and exit -v, --verbose print status messages, or debug with -vv -q, --quiet report only file names, or nothing with -qq --first show first occurrence of each error --exclude=patterns exclude files or directories which match these comma separated patterns (default: .svn,CVS,.bzr,.hg,.git) --filename=patterns when parsing directories, only check filenames matching these comma separated patterns (default: *.py) --select=errors select errors and warnings (e.g. E,W6) --ignore=errors skip errors and warnings (e.g. E4,W) --show-source show source code for each error --show-pep8 show text of PEP 8 for each error (implies --first) --statistics count errors and warnings --count print total number of errors and warnings to standard error and set exit code to 1 if total is not null --max-line-length=n set maximum allowed line length (default: 79) --max-doc-length=n set maximum allowed doc line length and perform these checks (unchecked if not set) --hang-closing hang closing bracket instead of matching indentation of opening bracket's line --format=format set the error format [default|pylint|] --diff report only lines changed according to the unified diff received on STDIN Testing Options: --benchmark measure processing speed Configuration: The project options are read from the [pycodestyle] section of the tox.ini file or the setup.cfg file located in any parent folder of the path(s) being processed. Allowed options are: exclude, filename, select, ignore, max-line-length, max-doc-length, hang-closing, count, format, quiet, show-pep8, show-source, statistics, verbose. --config=path user config file location (default: ~/.config/pycodestyle) Configuration ------------- The behaviour may be configured at two levels, the user and project levels. At the user level, settings are read from the following locations: If on Windows: ``~\.pycodestyle`` Otherwise, if the :envvar:`XDG_CONFIG_HOME` environment variable is defined: ``XDG_CONFIG_HOME/pycodestyle`` Else if :envvar:`XDG_CONFIG_HOME` is not defined: ``~/.config/pycodestyle`` Example:: [pycodestyle] count = False ignore = E226,E302,E41 max-line-length = 160 statistics = True At the project level, a ``setup.cfg`` file or a ``tox.ini`` file is read if present. If none of these files have a ``[pycodestyle]`` section, no project specific configuration is loaded. Error codes ----------- This is the current list of error and warning codes: +------------+----------------------------------------------------------------------+ | code | sample message | +============+======================================================================+ | **E1** | *Indentation* | +------------+----------------------------------------------------------------------+ | E101 | indentation contains mixed spaces and tabs | +------------+----------------------------------------------------------------------+ | E111 | indentation is not a multiple of four | +------------+----------------------------------------------------------------------+ | E112 | expected an indented block | +------------+----------------------------------------------------------------------+ | E113 | unexpected indentation | +------------+----------------------------------------------------------------------+ | E114 | indentation is not a multiple of four (comment) | +------------+----------------------------------------------------------------------+ | E115 | expected an indented block (comment) | +------------+----------------------------------------------------------------------+ | E116 | unexpected indentation (comment) | +------------+----------------------------------------------------------------------+ | E117 | over-indented | +------------+----------------------------------------------------------------------+ | E121 (\*^) | continuation line under-indented for hanging indent | +------------+----------------------------------------------------------------------+ | E122 (^) | continuation line missing indentation or outdented | +------------+----------------------------------------------------------------------+ | E123 (*) | closing bracket does not match indentation of opening bracket's line | +------------+----------------------------------------------------------------------+ | E124 (^) | closing bracket does not match visual indentation | +------------+----------------------------------------------------------------------+ | E125 (^) | continuation line with same indent as next logical line | +------------+----------------------------------------------------------------------+ | E126 (\*^) | continuation line over-indented for hanging indent | +------------+----------------------------------------------------------------------+ | E127 (^) | continuation line over-indented for visual indent | +------------+----------------------------------------------------------------------+ | E128 (^) | continuation line under-indented for visual indent | +------------+----------------------------------------------------------------------+ | E129 (^) | visually indented line with same indent as next logical line | +------------+----------------------------------------------------------------------+ | E131 (^) | continuation line unaligned for hanging indent | +------------+----------------------------------------------------------------------+ | E133 (*) | closing bracket is missing indentation | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **E2** | *Whitespace* | +------------+----------------------------------------------------------------------+ | E201 | whitespace after '(' | +------------+----------------------------------------------------------------------+ | E202 | whitespace before ')' | +------------+----------------------------------------------------------------------+ | E203 | whitespace before ':' | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | E211 | whitespace before '(' | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | E221 | multiple spaces before operator | +------------+----------------------------------------------------------------------+ | E222 | multiple spaces after operator | +------------+----------------------------------------------------------------------+ | E223 | tab before operator | +------------+----------------------------------------------------------------------+ | E224 | tab after operator | +------------+----------------------------------------------------------------------+ | E225 | missing whitespace around operator | +------------+----------------------------------------------------------------------+ | E226 (*) | missing whitespace around arithmetic operator | +------------+----------------------------------------------------------------------+ | E227 | missing whitespace around bitwise or shift operator | +------------+----------------------------------------------------------------------+ | E228 | missing whitespace around modulo operator | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | E231 | missing whitespace after ',', ';', or ':' | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | E241 (*) | multiple spaces after ',' | +------------+----------------------------------------------------------------------+ | E242 (*) | tab after ',' | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | E251 | unexpected spaces around keyword / parameter equals | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | E261 | at least two spaces before inline comment | +------------+----------------------------------------------------------------------+ | E262 | inline comment should start with '# ' | +------------+----------------------------------------------------------------------+ | E265 | block comment should start with '# ' | +------------+----------------------------------------------------------------------+ | E266 | too many leading '#' for block comment | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | E271 | multiple spaces after keyword | +------------+----------------------------------------------------------------------+ | E272 | multiple spaces before keyword | +------------+----------------------------------------------------------------------+ | E273 | tab after keyword | +------------+----------------------------------------------------------------------+ | E274 | tab before keyword | +------------+----------------------------------------------------------------------+ | E275 | missing whitespace after keyword | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **E3** | *Blank line* | +------------+----------------------------------------------------------------------+ | E301 | expected 1 blank line, found 0 | +------------+----------------------------------------------------------------------+ | E302 | expected 2 blank lines, found 0 | +------------+----------------------------------------------------------------------+ | E303 | too many blank lines (3) | +------------+----------------------------------------------------------------------+ | E304 | blank lines found after function decorator | +------------+----------------------------------------------------------------------+ | E305 | expected 2 blank lines after end of function or class | +------------+----------------------------------------------------------------------+ | E306 | expected 1 blank line before a nested definition | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **E4** | *Import* | +------------+----------------------------------------------------------------------+ | E401 | multiple imports on one line | +------------+----------------------------------------------------------------------+ | E402 | module level import not at top of file | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **E5** | *Line length* | +------------+----------------------------------------------------------------------+ | E501 (^) | line too long (82 > 79 characters) | +------------+----------------------------------------------------------------------+ | E502 | the backslash is redundant between brackets | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **E7** | *Statement* | +------------+----------------------------------------------------------------------+ | E701 | multiple statements on one line (colon) | +------------+----------------------------------------------------------------------+ | E702 | multiple statements on one line (semicolon) | +------------+----------------------------------------------------------------------+ | E703 | statement ends with a semicolon | +------------+----------------------------------------------------------------------+ | E704 (*) | multiple statements on one line (def) | +------------+----------------------------------------------------------------------+ | E711 (^) | comparison to None should be 'if cond is None:' | +------------+----------------------------------------------------------------------+ | E712 (^) | comparison to True should be 'if cond is True:' or 'if cond:' | +------------+----------------------------------------------------------------------+ | E713 | test for membership should be 'not in' | +------------+----------------------------------------------------------------------+ | E714 | test for object identity should be 'is not' | +------------+----------------------------------------------------------------------+ | E721 (^) | do not compare types, use 'isinstance()' | +------------+----------------------------------------------------------------------+ | E722 | do not use bare except, specify exception instead | +------------+----------------------------------------------------------------------+ | E731 | do not assign a lambda expression, use a def | +------------+----------------------------------------------------------------------+ | E741 | do not use variables named 'l', 'O', or 'I' | +------------+----------------------------------------------------------------------+ | E742 | do not define classes named 'l', 'O', or 'I' | +------------+----------------------------------------------------------------------+ | E743 | do not define functions named 'l', 'O', or 'I' | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **E9** | *Runtime* | +------------+----------------------------------------------------------------------+ | E901 | SyntaxError or IndentationError | +------------+----------------------------------------------------------------------+ | E902 | IOError | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **W1** | *Indentation warning* | +------------+----------------------------------------------------------------------+ | W191 | indentation contains tabs | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **W2** | *Whitespace warning* | +------------+----------------------------------------------------------------------+ | W291 | trailing whitespace | +------------+----------------------------------------------------------------------+ | W292 | no newline at end of file | +------------+----------------------------------------------------------------------+ | W293 | blank line contains whitespace | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **W3** | *Blank line warning* | +------------+----------------------------------------------------------------------+ | W391 | blank line at end of file | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **W5** | *Line break warning* | +------------+----------------------------------------------------------------------+ | W503 (*)   | line break before binary operator                         | +------------+----------------------------------------------------------------------+ | W504 (*)   | line break after binary operator                         | +------------+----------------------------------------------------------------------+ | W505 (\*^) | doc line too long (82 > 79 characters) | +------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **W6** | *Deprecation warning* | +------------+----------------------------------------------------------------------+ | W601 | .has_key() is deprecated, use 'in' | +------------+----------------------------------------------------------------------+ | W602 | deprecated form of raising exception | +------------+----------------------------------------------------------------------+ | W603 | '<>' is deprecated, use '!=' | +------------+----------------------------------------------------------------------+ | W604 | backticks are deprecated, use 'repr()' | +------------+----------------------------------------------------------------------+ | W605 | invalid escape sequence '\x' | +------------+----------------------------------------------------------------------+ | W606 | 'async' and 'await' are reserved keywords starting with Python 3.7 | +------------+----------------------------------------------------------------------+ **(*)** In the default configuration, the checks **E121**, **E123**, **E126**, **E133**, **E226**, **E241**, **E242**, **E704**, **W503**, **W504** and **W505** are ignored because they are not rules unanimously accepted, and `PEP 8`_ does not enforce them. Please note that if the option **--ignore=errors** is used, the default configuration will be overridden and ignore only the check(s) you skip. The check **W503** is mutually exclusive with check **W504**. The check **E133** is mutually exclusive with check **E123**. Use switch ``--hang-closing`` to report **E133** instead of **E123**. Use switch ``--max-doc-length=n`` to report **W505**. **(^)** These checks can be disabled at the line level using the ``# noqa`` special comment. This possibility should be reserved for special cases. *Special cases aren't special enough to break the rules.* Note: most errors can be listed with such one-liner:: $ python pycodestyle.py --first --select E,W testsuite/ --format '%(code)s: %(text)s' .. _related-tools: Related tools ------------- The `flake8 checker `_ is a wrapper around ``pycodestyle`` and similar tools. It supports plugins. Other tools which use ``pycodestyle`` are referenced in the Wiki: `list of related tools `_. .. _PEP 8: http://www.python.org/dev/peps/pep-0008/ pycodestyle-2.5.0/docs/Makefile0000664000175000017500000001272013230006455020054 0ustar icordascicordasc00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pycodestyle.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pycodestyle.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/pycodestyle" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pycodestyle" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." pycodestyle-2.5.0/docs/api.rst0000664000175000017500000000502613230006455017720 0ustar icordascicordasc00000000000000=============== pycodestyle API =============== .. module:: pycodestyle The library provides classes which are usable by third party tools. .. contents:: :local: .. _main_classes: Checker Classes --------------- The :class:`StyleGuide` class is used to configure a style guide checker instance to check multiple files. The :class:`Checker` class can be used to check a single file. .. autoclass:: StyleGuide(parse_argv=False, config_file=None, parser=None, paths=None, report=None, **kwargs) .. automethod:: init_report(reporter=None) .. automethod:: check_files(paths=None) .. automethod:: input_file(filename, lines=None, expected=None, line_offset=0) .. automethod:: input_dir(dirname) .. automethod:: excluded(filename, parent=None) .. automethod:: ignore_code(code) .. automethod:: get_checks(argument_name) .. autoclass:: Checker(filename=None, lines=None, report=None, **kwargs) .. automethod:: readline .. automethod:: run_check(check, argument_names) .. automethod:: check_physical(line) .. automethod:: build_tokens_line .. automethod:: check_logical .. automethod:: check_ast .. automethod:: generate_tokens .. automethod:: check_all(expected=None, line_offset=0) .. _report_classes: Report Classes -------------- .. autoclass:: BaseReport(options) .. automethod:: start .. automethod:: stop .. automethod:: init_file(filename, lines, expected, line_offset) .. automethod:: increment_logical_line .. automethod:: error(line_number, offset, text, check) .. automethod:: get_file_results .. automethod:: get_count(prefix='') .. automethod:: get_statistics(prefix='') .. automethod:: print_statistics(prefix='') .. automethod:: print_benchmark .. autoclass:: FileReport .. autoclass:: StandardReport .. autoclass:: DiffReport Utilities --------- .. autofunction:: expand_indent(line) .. autofunction:: mute_string(text) .. autofunction:: read_config(options, args, arglist, parser) .. autofunction:: process_options(arglist=None, parse_argv=False, config_file=None) .. autofunction:: register_check(func_or_cls, codes=None) .. These ones are used internally, but they don't need advertising .. autofunction:: readlines(filename) .. autofunction:: isidentifier(word) .. autofunction:: stdin_get_value() .. autofunction:: parse_udiff(diff, patterns=None, parent='.') .. autofunction:: filename_match(filename, patterns, default=True) .. autofunction:: get_parser(prog='pycodestyle', version=pycodestyle.__version__) .. autofunction:: init_checks_registry() pycodestyle-2.5.0/docs/index.rst0000664000175000017500000000356713230006455020266 0ustar icordascicordasc00000000000000.. pycodestyle documentation master file pycodestyle's documentation =========================== *Python style guide checker* pycodestyle (formerly pep8) is a tool to check your Python code against some of the style conventions in `PEP 8`_. .. _PEP 8: http://www.python.org/dev/peps/pep-0008/ Contents: .. toctree:: :maxdepth: 2 intro advanced API developer * Online documentation: https://pycodestyle.readthedocs.io/ * Source code and issue tracker: https://github.com/pycqa/pycodestyle Indices and tables ================== * :ref:`genindex` * :ref:`search` Credits ======= Created by Johann C. Rocholl. Maintained by Florent Xicluna and Ian Lee. .. _license: License ======= The ``pycodestyle`` library is provided under the terms and conditions of the Expat license:: # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation files # (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. pycodestyle-2.5.0/docs/advanced.rst0000664000175000017500000000524113424054446020723 0ustar icordascicordasc00000000000000.. currentmodule:: pycodestyle ============== Advanced usage ============== Automated tests --------------- You can also execute ``pycodestyle`` tests from Python code. For example, this can be highly useful for automated testing of coding style conformance in your project:: import unittest import pycodestyle class TestCodeFormat(unittest.TestCase): def test_conformance(self): """Test that we conform to PEP-8.""" style = pycodestyle.StyleGuide(quiet=True) result = style.check_files(['file1.py', 'file2.py']) self.assertEqual(result.total_errors, 0, "Found code style errors (and warnings).") There's also a shortcut for checking a single file:: import pycodestyle fchecker = pycodestyle.Checker('testsuite/E27.py', show_source=True) file_errors = fchecker.check_all() print("Found %s errors (and warnings)" % file_errors) Configuring tests ----------------- You can configure automated ``pycodestyle`` tests in a variety of ways. For example, you can pass in a path to a configuration file that ``pycodestyle`` should use:: import pycodestyle style = pycodestyle.StyleGuide(config_file='/path/to/tox.ini') You can also set specific options explicitly:: style = pycodestyle.StyleGuide(ignore=['E501']) Skip file header ---------------- Another example is related to the `feature request #143 `_: skip a number of lines at the beginning and the end of a file. This use case is easy to implement through a custom wrapper for the PEP 8 library:: #!python import pycodestyle LINES_SLICE = slice(14, -20) class StyleGuide(pycodestyle.StyleGuide): """This subclass of pycodestyle.StyleGuide will skip the first and last lines of each file.""" def input_file(self, filename, lines=None, expected=None, line_offset=0): if lines is None: assert line_offset == 0 line_offset = LINES_SLICE.start or 0 lines = pycodestyle.readlines(filename)[LINES_SLICE] return super(StyleGuide, self).input_file( filename, lines=lines, expected=expected, line_offset=line_offset) if __name__ == '__main__': style = StyleGuide(parse_argv=True, config_file=True) report = style.check_files() if report.total_errors: raise SystemExit(1) This module declares a lines' window which skips 14 lines at the beginning and 20 lines at the end. If there's no line to skip at the end, it could be changed with ``LINES_SLICE = slice(14, None)`` for example. You can save it in a file and use it with the same options as the original ``pycodestyle``. pycodestyle-2.5.0/docs/make.bat0000664000175000017500000001176213230006455020026 0ustar icordascicordasc00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pycodestyle.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pycodestyle.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end pycodestyle-2.5.0/CHANGES.txt0000664000175000017500000005661413424055634017317 0ustar icordascicordasc00000000000000Changelog ========= 2.5.0 (2019-01-29) ------------------ New checks: * E117: Over-indented code blocks * W505: Maximum doc-string length only when configured with --max-doc-length Changes: * Remove support for EOL Python 2.6 and 3.3. PR #720. * Add E117 error for over-indented code blocks. * Allow W605 to be silenced by `# noqa` and fix the position reported by W605 * Allow users to omit blank lines around one-liner definitions of classes and functions * Include the function return annotation (``->``) as requiring surrounding whitespace only on Python 3 * Verify that only names can follow ``await``. Previously we allowed numbers and strings. * Add support for Python 3.7 * Fix detection of annotated argument defaults for E252 * Cprrect the position reported by W504 2.4.0 (2018-04-10) ------------------ New checks: * Add W504 warning for checking that a break doesn't happen after a binary operator. This check is ignored by default. PR #502. * Add W605 warning for invalid escape sequences in string literals. PR #676. * Add W606 warning for 'async' and 'await' reserved keywords being introduced in Python 3.7. PR #684. * Add E252 error for missing whitespace around equal sign in type annotated function arguments with defaults values. PR #717. Changes: * An internal bisect search has replaced a linear search in order to improve efficiency. PR #648. * pycodestyle now uses PyPI trove classifiers in order to document supported python versions on PyPI. PR #654. * 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as the former is legacy. PR #653. * pycodestyle now handles very long lines much more efficiently for python 3.2+. Fixes #643. PR #644. * You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve verbosity. PR #663. * The distribution of pycodestyle now includes the license text in order to comply with open source licenses which require this. PR #694. * 'maximum_line_length' now ignores shebang ('#!') lines. PR #736. * Add configuration option for the allowed number of blank lines. It is implemented as a top level dictionary which can be easily overwritten. Fixes #732. PR #733. Bugs: * Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused by an invalid escape sequence. PR #625. * Correctly report E501 when the first line of a docstring is too long. Resolves #622. PR #630. * Support variable annotation when variable start by a keyword, such as class variable type annotations in python 3.6. PR #640. * pycodestyle internals have been changed in order to allow 'python3 -m cProfile' to report correct metrics. PR #647. * Fix a spelling mistake in the description of E722. PR #697. * 'pycodestyle --diff' now does not break if your 'gitconfig' enables 'mnemonicprefix'. PR #706. 2.3.1 (2017-01-31) ------------------ Bugs: * Fix regression in detection of E302 and E306; #618, #620 2.3.0 (2017-01-30) ------------------ New Checks: * Add E722 warning for bare ``except`` clauses * Report E704 for async function definitions (``async def``) Bugs: * Fix another E305 false positive for variables beginning with "class" or "def" * Fix detection of multiple spaces between ``async`` and ``def`` * Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for variable annotations. 2.2.0 (2016-11-14) ------------------ Announcements: * Added Make target to obtain proper tarball file permissions; #599 Bugs: * Fixed E305 regression caused by #400; #593 2.1.0 (2016-11-04) ------------------ Announcements: * Change all references to the pep8 project to say pycodestyle; #530 Changes: * Report E302 for blank lines before an "async def"; #556 * Update our list of tested and supported Python versions which are 2.6, 2.7, 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy. * Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'. * Report E741 on 'global' and 'nonlocal' statements, as well as prohibited single-letter variables. * Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591 * Report E722 when bare except clause is used; #579 Bugs: * Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561 * Require two blank lines after toplevel def, class; #536 * Remove accidentally quadratic computation based on the number of colons. This will make pycodestyle faster in some cases; #314 2.0.0 (2016-05-31) ------------------ Announcements: * Repository renamed to `pycodestyle`; Issue #466 / #481. * Added joint Code of Conduct as member of PyCQA; #483 Changes: * Added tox test support for Python 3.5 and pypy3 * Added check E275 for whitespace on `from ... import ...` lines; #489 / #491 * Added W503 to the list of codes ignored by default ignore list; #498 * Removed use of project level `.pep8` configuration file; #364 Bugs: * Fixed bug with treating `~` operator as binary; #383 / #384 * Identify binary operators as unary; #484 / #485 1.7.0 (2016-01-12) ------------------ Announcements: * Repository moved to PyCQA Organization on GitHub: https://github.com/pycqa/pep8 Changes: * Reverted the fix in #368, "options passed on command line are only ones accepted" feature. This has many unintended consequences in pep8 and flake8 and needs to be reworked when I have more time. * Added support for Python 3.5. (Issue #420 & #459) * Added support for multi-line config_file option parsing. (Issue #429) * Improved parameter parsing. (Issues #420 & #456) Bugs: * Fixed BytesWarning on Python 3. (Issue #459) 1.6.2 (2015-02-15) ------------------ Changes: * Added check for breaking around a binary operator. (Issue #197, Pull #305) Bugs: * Restored config_file parameter in process_options(). (Issue #380) 1.6.1 (2015-02-08) ------------------ Changes: * Assign variables before referenced. (Issue #287) Bugs: * Exception thrown due to unassigned ``local_dir`` variable. (Issue #377) 1.6.0 (2015-02-06) ------------------ News: * Ian Lee joined the project as a maintainer. Changes: * Report E731 for lambda assignment. (Issue #277) * Report E704 for one-liner def instead of E701. Do not report this error in the default configuration. (Issue #277) * Replace codes E111, E112 and E113 with codes E114, E115 and E116 for bad indentation of comments. (Issue #274) * Report E266 instead of E265 when the block comment starts with multiple ``#``. (Issue #270) * Report E402 for import statements not at the top of the file. (Issue #264) * Do not enforce whitespaces around ``**`` operator. (Issue #292) * Strip whitespace from around paths during normalization. (Issue #339 / #343) * Update ``--format`` documentation. (Issue #198 / Pull Request #310) * Add ``.tox/`` to default excludes. (Issue #335) * Do not report E121 or E126 in the default configuration. (Issues #256 / #316) * Allow spaces around the equals sign in an annotated function. (Issue #357) * Allow trailing backslash if in an inline comment. (Issue #374) * If ``--config`` is used, only that configuration is processed. Otherwise, merge the user and local configurations are merged. (Issue #368 / #369) Bug fixes: * Don't crash if Checker.build_tokens_line() returns None. (Issue #306) * Don't crash if os.path.expanduser() throws an ImportError. (Issue #297) * Missing space around keyword parameter equal not always reported, E251. (Issue #323) * Fix false positive E711/E712/E713. (Issues #330 and #336) * Do not skip physical checks if the newline is escaped. (Issue #319) * Flush sys.stdout to avoid race conditions with printing. See flake8 bug: https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363) 1.5.7 (2014-05-29) ------------------ Bug fixes: * Skip the traceback on "Broken pipe" signal. (Issue #275) * Do not exit when an option in ``setup.cfg`` or ``tox.ini`` is not recognized. * Check the last line even if it does not end with a newline. (Issue #286) * Always open files in universal newlines mode in Python 2. (Issue #288) 1.5.6 (2014-04-14) ------------------ Bug fixes: * Check the last line even if it has no end-of-line. (Issue #273) 1.5.5 (2014-04-10) ------------------ Bug fixes: * Fix regression with E22 checks and inline comments. (Issue #271) 1.5.4 (2014-04-07) ------------------ Bug fixes: * Fix negative offset with E303 before a multi-line docstring. (Issue #269) 1.5.3 (2014-04-04) ------------------ Bug fixes: * Fix wrong offset computation when error is on the last char of a physical line. (Issue #268) 1.5.2 (2014-04-04) ------------------ Changes: * Distribute a universal wheel file. Bug fixes: * Report correct line number for E303 with comments. (Issue #60) * Do not allow newline after parameter equal. (Issue #252) * Fix line number reported for multi-line strings. (Issue #220) * Fix false positive E121/E126 with multi-line strings. (Issue #265) * Fix E501 not detected in comments with Python 2.5. * Fix caret position with ``--show-source`` when line contains tabs. 1.5.1 (2014-03-27) ------------------ Bug fixes: * Fix a crash with E125 on multi-line strings. (Issue #263) 1.5 (2014-03-26) ---------------- Changes: * Report E129 instead of E125 for visually indented line with same indent as next logical line. (Issue #126) * Report E265 for space before block comment. (Issue #190) * Report E713 and E714 when operators ``not in`` and ``is not`` are recommended. (Issue #236) * Allow long lines in multiline strings and comments if they cannot be wrapped. (Issue #224). * Optionally disable physical line checks inside multiline strings, using ``# noqa``. (Issue #242) * Change text for E121 to report "continuation line under-indented for hanging indent" instead of indentation not being a multiple of 4. * Report E131 instead of E121 / E126 if the hanging indent is not consistent within the same continuation block. It helps when error E121 or E126 is in the ``ignore`` list. * Report E126 instead of E121 when the continuation line is hanging with extra indentation, even if indentation is not a multiple of 4. Bug fixes: * Allow the checkers to report errors on empty files. (Issue #240) * Fix ignoring too many checks when ``--select`` is used with codes declared in a flake8 extension. (Issue #216) * Fix regression with multiple brackets. (Issue #214) * Fix ``StyleGuide`` to parse the local configuration if the keyword argument ``paths`` is specified. (Issue #246) * Fix a false positive E124 for hanging indent. (Issue #254) * Fix a false positive E126 with embedded colon. (Issue #144) * Fix a false positive E126 when indenting with tabs. (Issue #204) * Fix behaviour when ``exclude`` is in the configuration file and the current directory is not the project directory. (Issue #247) * The logical checks can return ``None`` instead of an empty iterator. (Issue #250) * Do not report multiple E101 if only the first indentation starts with a tab. (Issue #237) * Fix a rare false positive W602. (Issue #34) 1.4.6 (2013-07-02) ------------------ Changes: * Honor ``# noqa`` for errors E711 and E712. (Issue #180) * When both a ``tox.ini`` and a ``setup.cfg`` are present in the project directory, merge their contents. The ``tox.ini`` file takes precedence (same as before). (Issue #182) * Give priority to ``--select`` over ``--ignore``. (Issue #188) * Compare full path when excluding a file. (Issue #186) * New option ``--hang-closing`` to switch to the alternative style of closing bracket indentation for hanging indent. Add error E133 for closing bracket which is missing indentation. (Issue #103) * Accept both styles of closing bracket indentation for hanging indent. Do not report error E123 in the default configuration. (Issue #103) Bug fixes: * Do not crash when running AST checks and the document contains null bytes. (Issue #184) * Correctly report other E12 errors when E123 is ignored. (Issue #103) * Fix false positive E261/E262 when the file contains a BOM. (Issue #193) * Fix E701, E702 and E703 not detected sometimes. (Issue #196) * Fix E122 not detected in some cases. (Issue #201 and #208) * Fix false positive E121 with multiple brackets. (Issue #203) 1.4.5 (2013-03-06) ------------------ * When no path is specified, do not try to read from stdin. The feature was added in 1.4.3, but it is not supported on Windows. Use ``-`` filename argument to read from stdin. This usage is supported since 1.3.4. (Issue #170) * Do not require ``setuptools`` in setup.py. It works around an issue with ``pip`` and Python 3. (Issue #172) * Add ``__pycache__`` to the ignore list. * Change misleading message for E251. (Issue #171) * Do not report false E302 when the source file has a coding cookie or a comment on the first line. (Issue #174) * Reorganize the tests and add tests for the API and for the command line usage and options. (Issues #161 and #162) * Ignore all checks which are not explicitly selected when ``select`` is passed to the ``StyleGuide`` constructor. 1.4.4 (2013-02-24) ------------------ * Report E227 or E228 instead of E225 for whitespace around bitwise, shift or modulo operators. (Issue #166) * Change the message for E226 to make clear that it is about arithmetic operators. * Fix a false positive E128 for continuation line indentation with tabs. * Fix regression with the ``--diff`` option. (Issue #169) * Fix the ``TestReport`` class to print the unexpected warnings and errors. 1.4.3 (2013-02-22) ------------------ * Hide the ``--doctest`` and ``--testsuite`` options when installed. * Fix crash with AST checkers when the syntax is invalid. (Issue #160) * Read from standard input if no path is specified. * Initiate a graceful shutdown on ``Control+C``. * Allow changing the ``checker_class`` for the ``StyleGuide``. 1.4.2 (2013-02-10) ------------------ * Support AST checkers provided by third-party applications. * Register new checkers with ``register_check(func_or_cls, codes)``. * Allow constructing a ``StyleGuide`` with a custom parser. * Accept visual indentation without parenthesis after the ``if`` statement. (Issue #151) * Fix UnboundLocalError when using ``# noqa`` with continued lines. (Issue #158) * Re-order the lines for the ``StandardReport``. * Expand tabs when checking E12 continuation lines. (Issue #155) * Refactor the testing class ``TestReport`` and the specific test functions into a separate test module. 1.4.1 (2013-01-18) ------------------ * Allow sphinx.ext.autodoc syntax for comments. (Issue #110) * Report E703 instead of E702 for the trailing semicolon. (Issue #117) * Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149) * Expose the ``OptionParser`` factory for better extensibility. 1.4 (2012-12-22) ---------------- * Report E226 instead of E225 for optional whitespace around common operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error code is ignored in the default configuration because PEP 8 recommends to "use your own judgement". (Issue #96) * Lines with a ``# nopep8`` at the end will not issue errors on line length E501 or continuation line indentation E12*. (Issue #27) * Fix AssertionError when the source file contains an invalid line ending ``"\r\r\n"``. (Issue #119) * Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present. (Issue #93 and #141) * Add the Sphinx-based documentation, and publish it on https://pycodestyle.readthedocs.io/. (Issue #105) 1.3.4 (2012-12-18) ------------------ * Fix false positive E124 and E128 with comments. (Issue #100) * Fix error on stdin when running with bpython. (Issue #101) * Fix false positive E401. (Issue #104) * Report E231 for nested dictionary in list. (Issue #142) * Catch E271 at the beginning of the line. (Issue #133) * Fix false positive E126 for multi-line comments. (Issue #138) * Fix false positive E221 when operator is preceded by a comma. (Issue #135) * Fix ``--diff`` failing on one-line hunk. (Issue #137) * Fix the ``--exclude`` switch for directory paths. (Issue #111) * Use ``-`` filename to read from standard input. (Issue #128) 1.3.3 (2012-06-27) ------------------ * Fix regression with continuation line checker. (Issue #98) 1.3.2 (2012-06-26) ------------------ * Revert to the previous behaviour for ``--show-pep8``: do not imply ``--first``. (Issue #89) * Add E902 for IO errors. (Issue #87) * Fix false positive for E121, and missed E124. (Issue #92) * Set a sensible default path for config file on Windows. (Issue #95) * Allow ``verbose`` in the configuration file. (Issue #91) * Show the enforced ``max-line-length`` in the error message. (Issue #86) 1.3.1 (2012-06-18) ------------------ * Explain which configuration options are expected. Accept and recommend the options names with hyphen instead of underscore. (Issue #82) * Do not read the user configuration when used as a module (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor). * Fix wrong or missing cases for the E12 series. * Fix cases where E122 was missed. (Issue #81) 1.3 (2012-06-15) ---------------- .. warning:: The internal API is backwards incompatible. * Remove global configuration and refactor the library around a ``StyleGuide`` class; add the ability to configure various reporters. (Issue #35 and #66) * Read user configuration from ``~/.config/pep8`` and local configuration from ``./.pep8``. (Issue #22) * Fix E502 for backslash embedded in multi-line string. (Issue #68) * Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72) * Enable the new checkers from the E12 series in the default configuration. * Suggest less error-prone alternatives for E712 errors. * Rewrite checkers to run faster (E22, E251, E27). * Fixed a crash when parsed code is invalid (too many closing brackets). * Fix E127 and E128 for continuation line indentation. (Issue #74) * New option ``--format`` to customize the error format. (Issue #23) * New option ``--diff`` to check only modified code. The unified diff is read from STDIN. Example: ``hg diff | pep8 --diff`` (Issue #39) * Correctly report the count of failures and set the exit code to 1 when the ``--doctest`` or the ``--testsuite`` fails. * Correctly detect the encoding in Python 3. (Issue #69) * Drop support for Python 2.3, 2.4 and 3.0. (Issue #78) 1.2 (2012-06-01) ---------------- * Add E121 through E128 for continuation line indentation. These checks are disabled by default. If you want to force all checks, use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64) * Add E721 for direct type comparisons. (Issue #47) * Add E711 and E712 for comparisons to singletons. (Issue #46) * Fix spurious E225 and E701 for function annotations. (Issue #29) * Add E502 for explicit line join between brackets. * Fix E901 when printing source with ``--show-source``. * Report all errors for each checker, instead of reporting only the first occurrence for each line. * Option ``--show-pep8`` implies ``--first``. 1.1 (2012-05-24) ---------------- * Add E901 for syntax errors. (Issues #63 and #30) * Add E271, E272, E273 and E274 for extraneous whitespace around keywords. (Issue #57) * Add ``tox.ini`` configuration file for tests. (Issue #61) * Add ``.travis.yml`` configuration file for continuous integration. (Issue #62) 1.0.1 (2012-04-06) ------------------ * Fix inconsistent version numbers. 1.0 (2012-04-04) ---------------- * Fix W602 ``raise`` to handle multi-char names. (Issue #53) 0.7.0 (2012-03-26) ------------------ * Now ``--first`` prints only the first occurrence of each error. The ``--repeat`` flag becomes obsolete because it is the default behaviour. (Issue #6) * Allow specifying ``--max-line-length``. (Issue #36) * Make the shebang more flexible. (Issue #26) * Add testsuite to the bundle. (Issue #25) * Fixes for Jython. (Issue #49) * Add PyPI classifiers. (Issue #43) * Fix the ``--exclude`` option. (Issue #48) * Fix W602, accept ``raise`` with 3 arguments. (Issue #34) * Correctly select all tests if ``DEFAULT_IGNORE == ''``. 0.6.1 (2010-10-03) ------------------ * Fix inconsistent version numbers. (Issue #21) 0.6.0 (2010-09-19) ------------------ * Test suite reorganized and enhanced in order to check more failures with fewer test files. Read the ``run_tests`` docstring for details about the syntax. * Fix E225: accept ``print >>sys.stderr, "..."`` syntax. * Fix E501 for lines containing multibyte encoded characters. (Issue #7) * Fix E221, E222, E223, E224 not detected in some cases. (Issue #16) * Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17) * Exit code is always 1 if any error or warning is found. (Issue #10) * ``--ignore`` checks are now really ignored, especially in conjunction with ``--count``. (Issue #8) * Blank lines with spaces yield W293 instead of W291: some developers want to ignore this warning and indent the blank lines to paste their code easily in the Python interpreter. * Fix E301: do not require a blank line before an indented block. (Issue #14) * Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13) * Performance improvements. * Fix decoding and checking non-UTF8 files in Python 3. * Fix E225: reject ``True+False`` when running on Python 3. * Fix an exception when the line starts with an operator. * Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5) 0.5.0 (2010-02-17) ------------------ * Changed the ``--count`` switch to print to sys.stderr and set exit code to 1 if any error or warning is found. * E241 and E242 are removed from the standard checks. If you want to include these checks, use switch ``--select=E,W``. (Issue #4) * Blank line is not mandatory before the first class method or nested function definition, even if there's a docstring. (Issue #1) * Add the switch ``--version``. * Fix decoding errors with Python 3. (Issue #13 [1]_) * Add ``--select`` option which is mirror of ``--ignore``. * Add checks E261 and E262 for spaces before inline comments. * New check W604 warns about deprecated usage of backticks. * New check W603 warns about the deprecated operator ``<>``. * Performance improvement, due to rewriting of E225. * E225 now accepts: - no whitespace after unary operator or similar. (Issue #9 [1]_) - lambda function with argument unpacking or keyword defaults. * Reserve "2 blank lines" for module-level logical blocks. (E303) * Allow multi-line comments. (E302, issue #10 [1]_) 0.4.2 (2009-10-22) ------------------ * Decorators on classes and class methods are OK now. 0.4 (2009-10-20) ---------------- * Support for all versions of Python from 2.3 to 3.1. * New and greatly expanded self tests. * Added ``--count`` option to print the total number of errors and warnings. * Further improvements to the handling of comments and blank lines. (Issue #1 [1]_ and others changes.) * Check all py files in directory when passed a directory (Issue #2 [1]_). This also prevents an exception when traversing directories with non ``*.py`` files. * E231 should allow commas to be followed by ``)``. (Issue #3 [1]_) * Spaces are no longer required around the equals sign for keyword arguments or default parameter values. .. [1] These issues refer to the `previous issue tracker`__. .. __: http://github.com/cburroughs/pep8.py/issues 0.3.1 (2009-09-14) ------------------ * Fixes for comments: do not count them when checking for blank lines between items. * Added setup.py for pypi upload and easy_installability. 0.2 (2007-10-16) ---------------- * Loads of fixes and improvements. 0.1 (2006-10-01) ---------------- * First release. pycodestyle-2.5.0/dev-requirements.txt0000664000175000017500000000000413230006455021514 0ustar icordascicordasc00000000000000tox pycodestyle-2.5.0/MANIFEST.in0000664000175000017500000000036313230023456017222 0ustar icordascicordasc00000000000000include *.txt include *.rst include LICENSE recursive-include docs * recursive-include testsuite * recursive-exclude docs *.pyc recursive-exclude docs *.pyo recursive-exclude testsuite *.pyc recursive-exclude testsuite *.pyo prune docs/_build pycodestyle-2.5.0/setup.cfg0000664000175000017500000000027713424056203017312 0ustar icordascicordasc00000000000000[bdist_wheel] universal = 1 [metadata] license_file = LICENSE [pycodestyle] select = ignore = E226,E24,W504 max_line_length = 79 max_doc_length = 72 [egg_info] tag_build = tag_date = 0