diff -Nru pycodestyle-2.5.0/CHANGES.txt pycodestyle-2.6.0/CHANGES.txt --- pycodestyle-2.5.0/CHANGES.txt 2019-01-29 13:56:44.000000000 +0000 +++ pycodestyle-2.6.0/CHANGES.txt 2020-05-11 19:20:29.000000000 +0000 @@ -1,6 +1,45 @@ Changelog ========= +2.6.0 (2020-05-11) +------------------ + +Announcements: + +* Anthony Sottile (@asottile) joined the team as a core developer. :tada: + +Changes: + +* E306: fix detection inside ``async def``. PR #929. +* E301: fix regression disallowing decorated one-liners. PR #927. +* E714: fix false positive with chained ``is not``. PR #931. + + +2.6.0a1 (2020-04-23) +-------------------- + +New checks: + +* E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847. + +Changes: + +* E117: fix indentation using tabs by treating as 8-space indents. PR #837. +* E721: fix false positive with names containg ``istype``. PR #850. +* E741: allow ``l`` as a named argument in a function call. PR #853. +* E302: fix false-negative with decorated functions. PR #859. +* W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875. +* E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834. +* Add support for assignment expressions ``:=`` (PEP 572). PR #879. +* Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918. +* Add support for python 3.8. +* Add support for matrix multiplication operator ``@`` (PEP 465). PR #897. +* Support visual indent for continuation lines for ``with`` / ``assert`` / + ``raise``. PR #912. +* E302: allow two blank lines after a block of one-liners. PR #913. +* E302: allow two-and-fewer newlines at the top of the file. PR #919. + + 2.5.0 (2019-01-29) ------------------ @@ -22,7 +61,7 @@ and strings. * Add support for Python 3.7 * Fix detection of annotated argument defaults for E252 -* Cprrect the position reported by W504 +* Correct the position reported by W504 2.4.0 (2018-04-10) diff -Nru pycodestyle-2.5.0/CONTRIBUTING.rst pycodestyle-2.6.0/CONTRIBUTING.rst --- pycodestyle-2.5.0/CONTRIBUTING.rst 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/CONTRIBUTING.rst 2020-04-23 21:57:11.000000000 +0000 @@ -34,8 +34,10 @@ create, then activate a virtualenv:: $ cd pycodestyle - $ virtualenv pycodestyle-venv - $ source pycodestyle-venv/bin/activate + $ virtualenv venv-pycodestyle + $ source venv-pycodestyle/bin/activate + +Note that ``venv*/`` is ignored via ``.gitignore``. Now you can install the pycodestyle requirements:: diff -Nru pycodestyle-2.5.0/debian/changelog pycodestyle-2.6.0/debian/changelog --- pycodestyle-2.5.0/debian/changelog 2020-03-16 04:58:30.000000000 +0000 +++ pycodestyle-2.6.0/debian/changelog 2020-06-12 09:52:07.000000000 +0000 @@ -1,3 +1,15 @@ +pycodestyle (2.6.0-1) unstable; urgency=medium + + * New upstream release. + * d/copyright: Update for new upstream release. + * Bump debhelper compat level to 13. + * Set Rules-Requires-Root: no. + * Add d/pybuild.testfiles. + * Bump standards version to 4.5.0. + * Remove broken mention of testsuite from setup.py. + + -- Ondřej Nový Fri, 12 Jun 2020 11:52:07 +0200 + pycodestyle (2.5.0-3) unstable; urgency=medium * Drop python2 support; Closes: #937408 diff -Nru pycodestyle-2.5.0/debian/control pycodestyle-2.6.0/debian/control --- pycodestyle-2.5.0/debian/control 2020-03-16 04:58:30.000000000 +0000 +++ pycodestyle-2.6.0/debian/control 2020-06-12 09:45:12.000000000 +0000 @@ -3,14 +3,15 @@ Priority: optional Maintainer: Debian Python Modules Team Uploaders: Ondřej Nový -Build-Depends: debhelper-compat (= 12), +Build-Depends: debhelper-compat (= 13), dh-python, python3-all, python3-setuptools, -Standards-Version: 4.4.1 +Standards-Version: 4.5.0 Homepage: https://pypi.python.org/pypi/pycodestyle Vcs-Git: https://salsa.debian.org/python-team/modules/pycodestyle.git Vcs-Browser: https://salsa.debian.org/python-team/modules/pycodestyle +Rules-Requires-Root: no Package: pycodestyle Architecture: all diff -Nru pycodestyle-2.5.0/debian/copyright pycodestyle-2.6.0/debian/copyright --- pycodestyle-2.5.0/debian/copyright 2020-03-16 04:58:30.000000000 +0000 +++ pycodestyle-2.6.0/debian/copyright 2020-06-12 08:59:24.000000000 +0000 @@ -5,7 +5,7 @@ Files: * Copyright: 2006-2009 Johann C. Rocholl 2009-2014 Florent Xicluna - 2014-2017 Ian Lee + 2014-2020 Ian Lee License: Expat Files: debian/* diff -Nru pycodestyle-2.5.0/debian/patches/Remove-broken-mention-of-testsuite-from-setup.py.patch pycodestyle-2.6.0/debian/patches/Remove-broken-mention-of-testsuite-from-setup.py.patch --- pycodestyle-2.5.0/debian/patches/Remove-broken-mention-of-testsuite-from-setup.py.patch 1970-01-01 00:00:00.000000000 +0000 +++ pycodestyle-2.6.0/debian/patches/Remove-broken-mention-of-testsuite-from-setup.py.patch 2020-06-12 09:38:44.000000000 +0000 @@ -0,0 +1,18 @@ +From 11dd1c84879e476a4d3cb264d97bfea9bcfb30d6 Mon Sep 17 00:00:00 2001 +From: Dmitry Marakasov +Date: Tue, 26 May 2020 17:58:59 +0300 +Subject: [PATCH] Remove broken mention of testsuite from setup.py +Origin: https://github.com/PyCQA/pycodestyle/commit/11dd1c84879e476a4d3cb264d97bfea9bcfb30d6 + +--- + setup.py | 1 - + 1 file changed, 1 deletion(-) + +--- a/setup.py ++++ b/setup.py +@@ -63,5 +63,4 @@ + 'Programming Language :: Python :: Implementation :: PyPy', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], +- test_suite='testsuite.test_all.suite', + ) diff -Nru pycodestyle-2.5.0/debian/patches/series pycodestyle-2.6.0/debian/patches/series --- pycodestyle-2.5.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ pycodestyle-2.6.0/debian/patches/series 2020-06-12 09:38:03.000000000 +0000 @@ -0,0 +1 @@ +Remove-broken-mention-of-testsuite-from-setup.py.patch diff -Nru pycodestyle-2.5.0/debian/pybuild.testfiles pycodestyle-2.6.0/debian/pybuild.testfiles --- pycodestyle-2.5.0/debian/pybuild.testfiles 1970-01-01 00:00:00.000000000 +0000 +++ pycodestyle-2.6.0/debian/pybuild.testfiles 2020-06-12 09:43:30.000000000 +0000 @@ -0,0 +1,2 @@ +testsuite +setup.py diff -Nru pycodestyle-2.5.0/LICENSE pycodestyle-2.6.0/LICENSE --- pycodestyle-2.5.0/LICENSE 2018-04-10 11:24:38.000000000 +0000 +++ pycodestyle-2.6.0/LICENSE 2020-05-11 19:15:11.000000000 +0000 @@ -1,6 +1,6 @@ Copyright © 2006-2009 Johann C. Rocholl Copyright © 2009-2014 Florent Xicluna -Copyright © 2014-2018 Ian Lee +Copyright © 2014-2020 Ian Lee Licensed under the terms of the Expat License diff -Nru pycodestyle-2.5.0/PKG-INFO pycodestyle-2.6.0/PKG-INFO --- pycodestyle-2.5.0/PKG-INFO 2019-01-29 14:00:35.000000000 +0000 +++ pycodestyle-2.6.0/PKG-INFO 2020-05-11 19:56:03.000000000 +0000 @@ -1,12 +1,13 @@ Metadata-Version: 1.2 Name: pycodestyle -Version: 2.5.0 +Version: 2.6.0 Summary: Python style guide checker Home-page: https://pycodestyle.readthedocs.io/ -Author: Ian Lee -Author-email: IanLee1521@gmail.com +Author: Johann C. Rocholl +Author-email: johann@rocholl.net +Maintainer: Ian Lee +Maintainer-email: IanLee1521@gmail.com License: Expat license -Description-Content-Type: UNKNOWN Description: pycodestyle (formerly called pep8) - Python style guide checker =============================================================== @@ -120,6 +121,45 @@ Changelog ========= + 2.6.0 (2020-05-11) + ------------------ + + Announcements: + + * Anthony Sottile (@asottile) joined the team as a core developer. :tada: + + Changes: + + * E306: fix detection inside ``async def``. PR #929. + * E301: fix regression disallowing decorated one-liners. PR #927. + * E714: fix false positive with chained ``is not``. PR #931. + + + 2.6.0a1 (2020-04-23) + -------------------- + + New checks: + + * E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847. + + Changes: + + * E117: fix indentation using tabs by treating as 8-space indents. PR #837. + * E721: fix false positive with names containg ``istype``. PR #850. + * E741: allow ``l`` as a named argument in a function call. PR #853. + * E302: fix false-negative with decorated functions. PR #859. + * W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875. + * E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834. + * Add support for assignment expressions ``:=`` (PEP 572). PR #879. + * Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918. + * Add support for python 3.8. + * Add support for matrix multiplication operator ``@`` (PEP 465). PR #897. + * Support visual indent for continuation lines for ``with`` / ``assert`` / + ``raise``. PR #912. + * E302: allow two blank lines after a block of one-liners. PR #913. + * E302: allow two-and-fewer newlines at the top of the file. PR #919. + + 2.5.0 (2019-01-29) ------------------ @@ -141,7 +181,7 @@ and strings. * Add support for Python 3.7 * Fix detection of annotated argument defaults for E252 - * Cprrect the position reported by W504 + * Correct the position reported by W504 2.4.0 (2018-04-10) @@ -986,6 +1026,7 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules diff -Nru pycodestyle-2.5.0/pycodestyle.egg-info/PKG-INFO pycodestyle-2.6.0/pycodestyle.egg-info/PKG-INFO --- pycodestyle-2.5.0/pycodestyle.egg-info/PKG-INFO 2019-01-29 14:00:35.000000000 +0000 +++ pycodestyle-2.6.0/pycodestyle.egg-info/PKG-INFO 2020-05-11 19:56:03.000000000 +0000 @@ -1,12 +1,13 @@ Metadata-Version: 1.2 Name: pycodestyle -Version: 2.5.0 +Version: 2.6.0 Summary: Python style guide checker Home-page: https://pycodestyle.readthedocs.io/ -Author: Ian Lee -Author-email: IanLee1521@gmail.com +Author: Johann C. Rocholl +Author-email: johann@rocholl.net +Maintainer: Ian Lee +Maintainer-email: IanLee1521@gmail.com License: Expat license -Description-Content-Type: UNKNOWN Description: pycodestyle (formerly called pep8) - Python style guide checker =============================================================== @@ -120,6 +121,45 @@ Changelog ========= + 2.6.0 (2020-05-11) + ------------------ + + Announcements: + + * Anthony Sottile (@asottile) joined the team as a core developer. :tada: + + Changes: + + * E306: fix detection inside ``async def``. PR #929. + * E301: fix regression disallowing decorated one-liners. PR #927. + * E714: fix false positive with chained ``is not``. PR #931. + + + 2.6.0a1 (2020-04-23) + -------------------- + + New checks: + + * E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847. + + Changes: + + * E117: fix indentation using tabs by treating as 8-space indents. PR #837. + * E721: fix false positive with names containg ``istype``. PR #850. + * E741: allow ``l`` as a named argument in a function call. PR #853. + * E302: fix false-negative with decorated functions. PR #859. + * W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875. + * E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834. + * Add support for assignment expressions ``:=`` (PEP 572). PR #879. + * Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918. + * Add support for python 3.8. + * Add support for matrix multiplication operator ``@`` (PEP 465). PR #897. + * Support visual indent for continuation lines for ``with`` / ``assert`` / + ``raise``. PR #912. + * E302: allow two blank lines after a block of one-liners. PR #913. + * E302: allow two-and-fewer newlines at the top of the file. PR #919. + + 2.5.0 (2019-01-29) ------------------ @@ -141,7 +181,7 @@ and strings. * Add support for Python 3.7 * Fix detection of annotated argument defaults for E252 - * Cprrect the position reported by W504 + * Correct the position reported by W504 2.4.0 (2018-04-10) @@ -986,6 +1026,7 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules diff -Nru pycodestyle-2.5.0/pycodestyle.egg-info/SOURCES.txt pycodestyle-2.6.0/pycodestyle.egg-info/SOURCES.txt --- pycodestyle-2.5.0/pycodestyle.egg-info/SOURCES.txt 2019-01-29 14:00:35.000000000 +0000 +++ pycodestyle-2.6.0/pycodestyle.egg-info/SOURCES.txt 2020-05-11 19:56:03.000000000 +0000 @@ -52,6 +52,7 @@ testsuite/noqa.py testsuite/python3.py testsuite/python35.py +testsuite/python38.py testsuite/support.py testsuite/test_all.py testsuite/test_api.py diff -Nru pycodestyle-2.5.0/pycodestyle.py pycodestyle-2.6.0/pycodestyle.py --- pycodestyle-2.5.0/pycodestyle.py 2019-01-29 13:58:00.000000000 +0000 +++ pycodestyle-2.6.0/pycodestyle.py 2020-05-11 19:15:00.000000000 +0000 @@ -78,7 +78,7 @@ except ImportError: from ConfigParser import RawConfigParser -__version__ = '2.5.0' +__version__ = '2.6.0' DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503,W504' @@ -113,14 +113,17 @@ SINGLETONS = frozenset(['False', 'None', 'True']) KEYWORDS = frozenset(keyword.kwlist + ['print', 'async']) - SINGLETONS UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-']) -ARITHMETIC_OP = 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 [] +ASSIGNMENT_EXPRESSION_OP = [':='] if sys.version_info >= (3, 8) else [] WS_NEEDED_OPERATORS = frozenset([ '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<>', '<', '>', - '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '='] + - FUNCTION_RETURN_ANNOTATION_OP) + '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '=', + 'and', 'in', 'is', 'or'] + + FUNCTION_RETURN_ANNOTATION_OP + + ASSIGNMENT_EXPRESSION_OP) WHITESPACE = frozenset(' \t') NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE]) SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT]) @@ -133,12 +136,13 @@ 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'[\[({] | [\]}),;:]') +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' +COMPARE_NEGATIVE_REGEX = re.compile(r'\b(?%&^]+)(\s*)') @@ -311,6 +315,41 @@ ######################################################################## +def _is_one_liner(logical_line, indent_level, lines, line_number): + if not STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): + return False + + line_idx = line_number - 1 + + if line_idx < 1: + prev_indent = 0 + else: + prev_indent = expand_indent(lines[line_idx - 1]) + + if prev_indent > indent_level: + return False + + while line_idx < len(lines): + line = lines[line_idx].strip() + if not line.startswith('@') and STARTSWITH_TOP_LEVEL_REGEX.match(line): + break + else: + line_idx += 1 + else: + return False # invalid syntax: EOF while searching for def/class + + next_idx = line_idx + 1 + while next_idx < len(lines): + if lines[next_idx].strip(): + break + else: + next_idx += 1 + else: + return True # line is last in the file + + return expand_indent(lines[next_idx]) <= indent_level + + @register_check def blank_lines(logical_line, blank_lines, indent_level, line_number, blank_before, previous_logical, @@ -347,7 +386,7 @@ 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: + if not previous_logical and blank_before < top_level_lines: return # Don't expect blank lines before the first line if previous_logical.startswith('@'): if blank_lines: @@ -357,15 +396,11 @@ ): 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): + # allow a group of one-liners + if ( + _is_one_liner(logical_line, indent_level, lines, line_number) and + blank_before == 0 + ): return if indent_level: if not (blank_before == method_lines or @@ -379,7 +414,7 @@ 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 ') + nested = STARTSWITH_DEF_REGEX.match(line.lstrip()) if nested or ancestor_level == 0: break if nested: @@ -493,13 +528,16 @@ line = logical_line for index in range(len(line) - 1): char = line[index] - if char in ',;:' and line[index + 1] not in WHITESPACE: + next_char = line[index + 1] + if char in ',;:' and next_char 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] == ')': + if char == ',' and next_char == ')': continue # Allow tuple with only one element: (3,) + if char == ':' and next_char == '=' and sys.version_info >= (3, 8): + continue # Allow assignment expression yield index, "E231 missing whitespace after '%s'" % char @@ -534,9 +572,11 @@ 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') + if indent_expect: + expected_indent_amount = 8 if indent_char == '\t' else 4 + expected_indent_level = previous_indent_level + expected_indent_amount + if indent_level > expected_indent_level: + yield 0, tmpl % (7, 'over-indented') @register_check @@ -686,6 +726,9 @@ elif (token_type in (tokenize.STRING, tokenize.COMMENT) or text in ('u', 'ur', 'b', 'br')): indent_chances[start[1]] = str + # visual indent after assert/raise/with + elif not row and not depth and text in ["assert", "raise", "with"]: + indent_chances[end[1] + 1] = True # 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 @@ -822,6 +865,7 @@ E225: submitted +=1 E225: x = x /2 - 1 E225: z = x **y + E225: z = 1and 1 E226: c = (a+b) * (a-b) E226: hypot2 = x*x + y*y E227: c = a|b @@ -831,6 +875,7 @@ need_space = False prev_type = tokenize.OP prev_text = prev_end = None + operator_types = (tokenize.OP, tokenize.NAME) for token_type, text, start, end, line in tokens: if token_type in SKIP_COMMENTS: continue @@ -849,6 +894,19 @@ # Tolerate the "<>" operator, even if running Python 3 # Deal with Python 3's annotated return value "->" pass + elif ( + # def f(a, /, b): + # ^ + # def f(a, b, /): + # ^ + prev_text == '/' and text in {',', ')'} or + # def f(a, b, /): + # ^ + prev_text == ')' and text == ':' + ): + # Tolerate the "/" operator in function definition + # For more info see PEP570 + pass else: if need_space is True or need_space[1]: # A needed trailing space was not found @@ -862,7 +920,7 @@ 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: + elif token_type in operator_types and prev_end is not None: if text == '=' and parens: # Allow keyword args or defaults: foo(bar=None). pass @@ -1067,7 +1125,8 @@ line = line[1:] return line and (line[0] == '"' or line[0] == "'") - allowed_try_keywords = ('try', 'except', 'else', 'finally') + allowed_keywords = ( + 'try', 'except', 'else', 'finally', 'with', 'if', 'elif') if indent_level: # Allow imports in conditional statement/function return @@ -1081,9 +1140,9 @@ 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 + elif any(line.startswith(kw) for kw in allowed_keywords): + # Allow certain keywords intermixed with imports in order to + # support conditional or filtered importing return elif is_string_literal(line): # The first literal is a docstring, allow it. Otherwise, report @@ -1135,7 +1194,9 @@ update_counts(line[prev_found:found], counts) if ((counts['{'] <= counts['}'] and # {'a': 1} (dict) counts['['] <= counts[']'] and # [1:2] (slice) - counts['('] <= counts[')'])): # (annotation) + counts['('] <= counts[')']) and # (annotation) + not (sys.version_info >= (3, 8) and + line[found + 1] == '=')): # assignment expression lambda_kw = LAMBDA_REGEX.search(line, 0, found) if lambda_kw: before = line[:lambda_kw.start()].rstrip() @@ -1199,13 +1260,16 @@ parens -= 1 +_SYMBOLIC_OPS = frozenset("()[]{},:.;@=%~") | frozenset(("...",)) + + 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 "()[]{},:.;@=%~" + not_a_symbol = text and text not in _SYMBOLIC_OPS # 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. @@ -1418,28 +1482,58 @@ Variables can be bound in several other contexts, including class and function definitions, 'global' and 'nonlocal' statements, - exception handlers, and 'with' statements. + exception handlers, and 'with' and 'for' statements. + In addition, we have a special handling for function parameters. Okay: except AttributeError as o: Okay: with lock as L: + Okay: foo(l=12) + Okay: for a in foo(l=12): E741: except AttributeError as O: E741: with lock as l: E741: global I E741: nonlocal l + E741: def foo(l): + E741: def foo(l=12): + E741: l = foo(l=12) + E741: for l in range(10): E742: class I(object): E743: def l(x): """ + is_func_def = False # Set to true if 'def' is found + parameter_parentheses_level = 0 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 + # find function definitions + if prev_text == 'def': + is_func_def = True + # update parameter parentheses level + if parameter_parentheses_level == 0 and \ + prev_type == tokenize.NAME and \ + token_type == tokenize.OP and text == '(': + parameter_parentheses_level = 1 + elif parameter_parentheses_level > 0 and \ + token_type == tokenize.OP: + if text == '(': + parameter_parentheses_level += 1 + elif text == ')': + parameter_parentheses_level -= 1 # identifiers on the lhs of an assignment operator - if token_type == tokenize.OP and '=' in text: + if token_type == tokenize.OP and '=' in text and \ + parameter_parentheses_level == 0: 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'): + # identifiers bound to values with 'as', 'for', + # 'global', or 'nonlocal' + if prev_text in ('as', 'for', 'global', 'nonlocal'): + if text in idents_to_avoid: + ident = text + pos = start + # function parameter definitions + if is_func_def: if text in idents_to_avoid: ident = text pos = start @@ -1451,6 +1545,7 @@ yield start, "E743 ambiguous function definition '%s'" % text if ident: yield pos, "E741 ambiguous variable name '%s'" % ident + prev_type = token_type prev_text = text prev_start = start @@ -1742,6 +1837,7 @@ >>> expand_indent(' \t') 16 """ + line = line.rstrip('\n\r') if '\t' not in line: return len(line) - len(line.lstrip()) result = 0 diff -Nru pycodestyle-2.5.0/setup.py pycodestyle-2.6.0/setup.py --- pycodestyle-2.5.0/setup.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/setup.py 2020-04-23 21:57:11.000000000 +0000 @@ -58,6 +58,7 @@ 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Libraries :: Python Modules', diff -Nru pycodestyle-2.5.0/testsuite/E10.py pycodestyle-2.6.0/testsuite/E10.py --- pycodestyle-2.5.0/testsuite/E10.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E10.py 2020-04-23 21:57:11.000000000 +0000 @@ -3,7 +3,7 @@ for b in 'xyz': print a # indented with 8 spaces print b # indented with 1 tab -#: E101 E117 E122 W191 W191 +#: E101 E122 W191 W191 if True: pass @@ -27,7 +27,7 @@ pass # -#: E101 E117 W191 W191 +#: E101 W191 W191 if True: foo(1, 2) diff -Nru pycodestyle-2.5.0/testsuite/E11.py pycodestyle-2.6.0/testsuite/E11.py --- pycodestyle-2.5.0/testsuite/E11.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E11.py 2020-04-23 21:57:11.000000000 +0000 @@ -37,3 +37,6 @@ #: E117 def start(): print +#: E117 W191 +def start(): + print diff -Nru pycodestyle-2.5.0/testsuite/E12not.py pycodestyle-2.6.0/testsuite/E12not.py --- pycodestyle-2.5.0/testsuite/E12not.py 2018-04-10 11:24:38.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E12not.py 2020-04-23 21:57:11.000000000 +0000 @@ -639,3 +639,23 @@ # more stuff ) ) + + +def foo(): + pass + raise 123 + \ + 123 + + +class Eggs: + pass + assert 123456 == \ + 123456 + + +def f1(): + print('foo') + with open('/path/to/some/file/you/want/to/read') as file_1, \ + open('/path/to/some/file/being/written', 'w') as file_2, \ + open('just-making-sure-more-continuations-also-work'): + file_2.write(file_1.read()) diff -Nru pycodestyle-2.5.0/testsuite/E12.py pycodestyle-2.6.0/testsuite/E12.py --- pycodestyle-2.5.0/testsuite/E12.py 2018-04-10 11:24:38.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E12.py 2020-04-23 21:57:11.000000000 +0000 @@ -372,4 +372,26 @@ print(a , end=' ') -#: +#: E127:4:12 +def foo(): + pass + raise 123 + \ + 123 +#: E127:4:13 +class Eggs: + pass + assert 123456 == \ + 123456 +#: E127:4:11 +def f1(): + print('foo') + with open('/path/to/some/file/you/want/to/read') as file_1, \ + open('/path/to/some/file/being/written', 'w') as file_2: + file_2.write(file_1.read()) +#: E127:5:11 +def f1(): + print('foo') + with open('/path/to/some/file/you/want/to/read') as file_1, \ + open('/path/to/some/file/being/written', 'w') as file_2, \ + open('later-misindent'): + file_2.write(file_1.read()) diff -Nru pycodestyle-2.5.0/testsuite/E22.py pycodestyle-2.6.0/testsuite/E22.py --- pycodestyle-2.5.0/testsuite/E22.py 2018-01-18 04:48:46.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E22.py 2020-04-23 21:57:11.000000000 +0000 @@ -76,6 +76,18 @@ i=i+ 1 #: E225 E225 i=i +1 +#: E225 +i = 1and 1 +#: E225 +i = 1or 0 +#: E225 +1is 1 +#: E225 +1in [] +#: E225 +i = 1 @2 +#: E225 +i = 1@ 2 #: E225 E226 i=i+1 #: E225 E226 @@ -142,6 +154,7 @@ print >>sys.stderr, "x is out of range." print >> sys.stdout, "x is an integer." x = x / 2 - 1 +x = 1 @ 2 if alpha[:-i]: *a, b = (1, 2, 3) diff -Nru pycodestyle-2.5.0/testsuite/E30not.py pycodestyle-2.6.0/testsuite/E30not.py --- pycodestyle-2.5.0/testsuite/E30not.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E30not.py 2020-05-11 19:15:00.000000000 +0000 @@ -167,9 +167,49 @@ # for no E30x being emitted. def bar(): pass def baz(): pass + + +def main(): + 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 +#: E704:8:1 E704:10:1 +from typing import overload +from typing import Union + + +# This emits the (ignored-by-default) E704, but here we're testing +# for no E30x being emitted. +@overload +def f(x: int) -> int: ... +@overload +def f(x: str) -> str: ... + + +def f(x: Union[int, str]) -> Union[int, str]: + return x +#: E704:8:5 E704:10:5 +from typing import Protocol + + +class C(Protocol): + # This emits the (ignored-by-default) E704, but here we're testing + # for no E30x being emitted. + @property + def f(self) -> int: ... + @property + def g(self) -> str: ... +#: Okay +#!python +# -*- coding: utf-8 -*- +def a(): + pass +#: Okay +def f( + a, +): + pass diff -Nru pycodestyle-2.5.0/testsuite/E30.py pycodestyle-2.6.0/testsuite/E30.py --- pycodestyle-2.5.0/testsuite/E30.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E30.py 2020-05-11 19:15:00.000000000 +0000 @@ -16,11 +16,6 @@ #: -#: E302:3:1 -#!python -# -*- coding: utf-8 -*- -def a(): - pass #: E302:2:1 """Main module.""" def _main(): @@ -129,6 +124,11 @@ x = 1 def b(): pass +#: E306:3:5 +async def a(): + x = 1 + def b(): + pass #: E306:3:5 E306:5:9 def a(): x = 2 @@ -181,3 +181,11 @@ def bar(): pass def baz(): pass +#: E302:5:1 +def f(): + pass + +# wat +@hi +def g(): + pass diff -Nru pycodestyle-2.5.0/testsuite/E40.py pycodestyle-2.6.0/testsuite/E40.py --- pycodestyle-2.5.0/testsuite/E40.py 2018-01-18 04:48:46.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E40.py 2020-04-23 21:57:11.000000000 +0000 @@ -34,6 +34,21 @@ print('made attempt to import foo') import bar +#: Okay +with warnings.catch_warnings(): + warnings.filterwarnings("ignore", DeprecationWarning) + import foo + +import bar +#: Okay +if False: + import foo +elif not True: + import bar +else: + import mwahaha + +import bar #: E402 VERSION = '1.2.3' diff -Nru pycodestyle-2.5.0/testsuite/E71.py pycodestyle-2.6.0/testsuite/E71.py --- pycodestyle-2.5.0/testsuite/E71.py 2017-01-27 20:50:20.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E71.py 2020-05-11 19:15:00.000000000 +0000 @@ -64,6 +64,12 @@ #: E714 if not X.B is Y: pass +#: E714 +if not X is Y is not Z: + pass +#: E714 +if not X is not Y: + pass # #: Okay @@ -79,6 +85,9 @@ if x is not y: pass +if X is not Y is not Z: + pass + if TrueElement.get_element(True) == TrueElement.get_element(False): pass diff -Nru pycodestyle-2.5.0/testsuite/E72.py pycodestyle-2.6.0/testsuite/E72.py --- pycodestyle-2.5.0/testsuite/E72.py 2018-01-18 04:48:46.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E72.py 2020-04-23 21:57:11.000000000 +0000 @@ -49,6 +49,9 @@ pass if type(a) != type(b) or type(a) == type(ccc): pass +#: Okay +def func_histype(a, b, c): + pass #: E722 try: pass diff -Nru pycodestyle-2.5.0/testsuite/E90.py pycodestyle-2.6.0/testsuite/E90.py --- pycodestyle-2.5.0/testsuite/E90.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/E90.py 2020-04-23 21:57:11.000000000 +0000 @@ -2,7 +2,7 @@ } #: E901 = [x -#: E901 E101 E117 W191 +#: E901 E101 W191 while True: try: pass diff -Nru pycodestyle-2.5.0/testsuite/python38.py pycodestyle-2.6.0/testsuite/python38.py --- pycodestyle-2.5.0/testsuite/python38.py 1970-01-01 00:00:00.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/python38.py 2020-04-23 21:57:11.000000000 +0000 @@ -0,0 +1,27 @@ +#: Okay +def f1(a, /, b): + pass + + +def f2(a, b, /): + pass + + +def f3( + a, + /, + b, +): + pass +#: Okay +if x := 1: + print(x) +if m and (token := m.group(1)): + pass +stuff = [[y := f(x), x / y] for x in range(5)] +#: E225:1:5 +if x:= 1: + pass +#: E225:1:18 +if False or (x :=1): + pass diff -Nru pycodestyle-2.5.0/testsuite/python3.py pycodestyle-2.6.0/testsuite/python3.py --- pycodestyle-2.5.0/testsuite/python3.py 2018-01-18 04:48:46.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/python3.py 2020-04-23 21:57:11.000000000 +0000 @@ -37,3 +37,10 @@ def m(self): xs: List[int] = [] + + +# Used to trigger W504 +def f( + x: str = ... +): + ... diff -Nru pycodestyle-2.5.0/testsuite/test_all.py pycodestyle-2.6.0/testsuite/test_all.py --- pycodestyle-2.5.0/testsuite/test_all.py 2018-04-10 11:24:38.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/test_all.py 2020-04-23 21:57:11.000000000 +0000 @@ -45,31 +45,3 @@ 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()) diff -Nru pycodestyle-2.5.0/testsuite/test_api.py pycodestyle-2.6.0/testsuite/test_api.py --- pycodestyle-2.5.0/testsuite/test_api.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/test_api.py 2020-04-23 21:57:11.000000000 +0000 @@ -43,8 +43,7 @@ def test_register_physical_check(self): def check_dummy(physical_line, line_number): - if False: - yield + raise NotImplementedError pycodestyle.register_check(check_dummy, ['Z001']) self.assertTrue(check_dummy in pycodestyle._checks['physical_line']) @@ -53,13 +52,12 @@ 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)) + functions = [func for _, func, _ in options.physical_checks] + self.assertIn(check_dummy, functions) def test_register_logical_check(self): def check_dummy(logical_line, tokens): - if False: - yield + raise NotImplementedError pycodestyle.register_check(check_dummy, ['Z401']) self.assertTrue(check_dummy in pycodestyle._checks['logical_line']) @@ -74,8 +72,8 @@ self.assertEqual(args, ['logical_line', 'tokens']) options = pycodestyle.StyleGuide().options - self.assertTrue(any(func == check_dummy - for name, func, args in options.logical_checks)) + functions = [func for _, func, _ in options.logical_checks] + self.assertIn(check_dummy, functions) def test_register_ast_check(self): pycodestyle.register_check(DummyChecker, ['Z701']) @@ -86,17 +84,17 @@ self.assertTrue(args is None) options = pycodestyle.StyleGuide().options - self.assertTrue(any(cls == DummyChecker - for name, cls, args in options.ast_checks)) + classes = [cls for _, cls, _ in options.ast_checks] + self.assertIn(DummyChecker, classes) def test_register_invalid_check(self): class InvalidChecker(DummyChecker): def __init__(self, filename): - pass + raise NotImplementedError def check_dummy(logical, tokens): - if False: - yield + raise NotImplementedError + pycodestyle.register_check(InvalidChecker, ['Z741']) pycodestyle.register_check(check_dummy, ['Z441']) @@ -125,7 +123,7 @@ 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.assertEqual(report.total_errors, 24) self.assertFalse(sys.stderr) self.reset() @@ -133,7 +131,7 @@ 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.assertEqual(report.total_errors, 24) self.assertFalse(sys.stderr) self.reset() @@ -272,28 +270,28 @@ # Do run E11 checks options = pycodestyle.StyleGuide().options - self.assertTrue(any(func == pycodestyle.indentation - for name, func, args in options.logical_checks)) + functions = [func for _, func, _ in options.logical_checks] + self.assertIn(pycodestyle.indentation, functions) options = pycodestyle.StyleGuide(select=['E']).options - self.assertTrue(any(func == pycodestyle.indentation - for name, func, args in options.logical_checks)) + functions = [func for _, func, _ in options.logical_checks] + self.assertIn(pycodestyle.indentation, functions) options = pycodestyle.StyleGuide(ignore=['W']).options - self.assertTrue(any(func == pycodestyle.indentation - for name, func, args in options.logical_checks)) + functions = [func for _, func, _ in options.logical_checks] + self.assertIn(pycodestyle.indentation, functions) options = pycodestyle.StyleGuide(ignore=['E12']).options - self.assertTrue(any(func == pycodestyle.indentation - for name, func, args in options.logical_checks)) + functions = [func for _, func, _ in options.logical_checks] + self.assertIn(pycodestyle.indentation, functions) # 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)) + functions = [func for _, func, _ in options.logical_checks] + self.assertNotIn(pycodestyle.indentation, functions) options = pycodestyle.StyleGuide(ignore=['E']).options - self.assertFalse(any(func == pycodestyle.indentation - for name, func, args in options.logical_checks)) + functions = [func for _, func, _ in options.logical_checks] + self.assertNotIn(pycodestyle.indentation, functions) options = pycodestyle.StyleGuide(ignore=['E11']).options - self.assertFalse(any(func == pycodestyle.indentation - for name, func, args in options.logical_checks)) + functions = [func for _, func, _ in options.logical_checks] + self.assertNotIn(pycodestyle.indentation, functions) def test_styleguide_init_report(self): style = pycodestyle.StyleGuide(paths=[E11]) @@ -327,9 +325,7 @@ 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') + source = u'#\n' pep8style = pycodestyle.StyleGuide() count_errors = pep8style.input_file('stdin', lines=[source]) @@ -345,13 +341,9 @@ 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. + if 'ValueError' in stdout: # pragma: no cover (python 3.5+) expected = "stdin:1:1: E901 ValueError" - else: + else: # pragma: no cover (< python3.5) expected = "stdin:1:1: E901 TypeError" self.assertTrue(stdout.startswith(expected), msg='Output %r does not start with %r' % diff -Nru pycodestyle-2.5.0/testsuite/test_blank_lines.py pycodestyle-2.6.0/testsuite/test_blank_lines.py --- pycodestyle-2.5.0/testsuite/test_blank_lines.py 2018-05-19 12:13:18.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/test_blank_lines.py 2020-04-23 21:57:11.000000000 +0000 @@ -139,7 +139,6 @@ pass """) self.assertEqual([ - 'E302:4:1', # some_function 'E302:7:1', # another_function 'E302:14:1', # SomeCloseClass ], result) @@ -438,7 +437,7 @@ def test_top_level_fewer_blank_lines(self): """ - It will trigger an error when less 2 blank lines are found + It will trigger an error when less 3 blank lines are found before top level definitions. """ result = self.check("""# First comment line. @@ -471,7 +470,6 @@ pass """) self.assertEqual([ - 'E302:5:1', # some_function 'E302:9:1', # another_function 'E302:17:1', # SomeCloseClass ], result) diff -Nru pycodestyle-2.5.0/testsuite/test_shell.py pycodestyle-2.6.0/testsuite/test_shell.py --- pycodestyle-2.5.0/testsuite/test_shell.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/test_shell.py 2020-04-23 21:57:11.000000000 +0000 @@ -77,7 +77,7 @@ stdout = stdout.splitlines() self.assertEqual(errcode, 1) self.assertFalse(stderr) - self.assertEqual(len(stdout), 20) + self.assertEqual(len(stdout), 24) 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)) diff -Nru pycodestyle-2.5.0/testsuite/W19.py pycodestyle-2.6.0/testsuite/W19.py --- pycodestyle-2.5.0/testsuite/W19.py 2019-01-29 13:46:14.000000000 +0000 +++ pycodestyle-2.6.0/testsuite/W19.py 2020-04-23 21:57:11.000000000 +0000 @@ -1,4 +1,4 @@ -#: E117 W191 +#: W191 if False: print # indented with 1 tab #: @@ -7,30 +7,30 @@ #: W191 y = x == 2 \ or x == 3 -#: E101 E117 W191 W504 +#: E101 W191 W504 if ( x == ( 3 ) or y == 4): pass -#: E101 E117 W191 +#: E101 W191 if x == 2 \ or y > 1 \ or x == 3: pass -#: E101 E117 W191 +#: E101 W191 if x == 2 \ or y > 1 \ or x == 3: pass #: -#: E101 E117 W191 W504 +#: E101 W191 W504 if (foo == bar and baz == frop): pass -#: E101 E117 W191 W504 +#: E101 W191 W504 if ( foo == bar and baz == frop @@ -38,25 +38,25 @@ pass #: -#: E101 E101 E117 W191 W191 +#: E101 E101 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 +#: E101 W191 def long_function_name( var_one, var_two, var_three, var_four): print(var_one) -#: E101 E117 W191 W504 +#: E101 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 +#: E101 E101 E101 E101 W191 W191 W191 W191 W191 W191 if bar: return( start, 'E121 lines starting with a ' @@ -65,35 +65,35 @@ "bracket's line" ) # -#: E101 E117 W191 W504 +#: E101 W191 W504 # you want vertical alignment, so use a parens if ((foo.bar("baz") and foo.bar("frop") )): print "yes" -#: E101 E117 W191 W504 +#: E101 W191 W504 # also ok, but starting to look like LISP if ((foo.bar("baz") and foo.bar("frop"))): print "yes" -#: E101 E117 W191 W504 +#: E101 W191 W504 if (a == 2 or b == "abc def ghi" "jkl mno"): return True -#: E101 E117 W191 W504 +#: E101 W191 W504 if (a == 2 or b == """abc def ghi jkl mno"""): return True -#: W191:2:1 W191:3:1 E101:3:2 E117 +#: W191:2:1 W191:3:1 E101:3:2 if length > options.max_line_length: return options.max_line_length, \ "E501 line too long (%d characters)" % length # -#: E101 E117 W191 W191 W504 +#: E101 W191 W191 W504 if os.path.exists(os.path.join(path, PEP8_BIN)): cmd = ([os.path.join(path, PEP8_BIN)] + self._pep8_options(targetfile)) @@ -119,19 +119,19 @@ even though the noqa comment is not immediately after the string ''' + foo # noqa # -#: E101 E117 W191 +#: E101 W191 if foo is None and bar is "frop" and \ blah == 'yeah': blah = 'yeahnah' # -#: E117 W191 W191 W191 +#: W191 W191 W191 if True: foo( 1, 2) -#: E117 W191 W191 W191 W191 W191 +#: W191 W191 W191 W191 W191 def test_keys(self): """areas.json - All regions are accounted for.""" expected = set([