diff options
-rw-r--r-- | .travis.yml | 12 | ||||
-rw-r--r-- | CHANGES.txt | 28 | ||||
-rw-r--r-- | CONTRIBUTING.rst | 4 | ||||
-rw-r--r-- | LICENSE | 1 | ||||
-rw-r--r-- | README.rst | 6 | ||||
-rw-r--r-- | docs/advanced.rst | 2 | ||||
-rw-r--r-- | docs/conf.py | 8 | ||||
-rw-r--r-- | docs/developer.rst | 26 | ||||
-rw-r--r-- | docs/index.rst | 2 | ||||
-rw-r--r-- | docs/intro.rst | 383 | ||||
-rwxr-xr-x | pep8.py | 85 | ||||
-rw-r--r-- | testsuite/E71.py | 18 | ||||
-rw-r--r-- | testsuite/test_all.py | 3 | ||||
-rw-r--r-- | testsuite/test_api.py | 3 | ||||
-rw-r--r-- | testsuite/test_parser.py | 61 | ||||
-rw-r--r-- | tox.ini | 4 |
16 files changed, 410 insertions, 236 deletions
diff --git a/.travis.yml b/.travis.yml index b188325..3149cbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,13 @@ language: python +sudo: false python: - 2.6 - 2.7 - 3.2 - 3.3 - 3.4 + - 3.5 + - nightly - pypy - pypy3 install: @@ -15,11 +18,12 @@ script: - python pep8.py --statistics pep8.py - python pep8.py --doctest - python setup.py test -matrix: - allow_failures: - - python: pypy - - python: pypy3 notifications: email: - IanLee1521@gmail.com + irc: + channels: + - "irc.freenode.org##python-code-quality" + use_notice: true + skip_join: true diff --git a/CHANGES.txt b/CHANGES.txt index dc22f24..6e853eb 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,34 @@ Changelog ========= +1.8.0 (unreleased) +------------------ + +Announcements: + +* Repository renamed to `pycodestyle`; Issue #466 / $481. + +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) ------------------ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..158dc6f --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,4 @@ +Contributing to ``pep8`` +======================== + +Please see the `developer notes <https://pep8.readthedocs.org/en/latest/developer.html>`_ @@ -1,5 +1,6 @@ Copyright © 2006-2009 Johann C. Rocholl <johann@rocholl.net> Copyright © 2009-2014 Florent Xicluna <florent.xicluna@gmail.com> +Copyright © 2014-2016 Ian Lee <IanLee1521@gmail.com> Licensed under the terms of the Expat License @@ -78,8 +78,8 @@ Or you can display how often each error was found:: Links ----- -.. image:: https://api.travis-ci.org/jcrocholl/pep8.png?branch=master - :target: https://travis-ci.org/jcrocholl/pep8 +.. image:: https://api.travis-ci.org/PyCQA/pep8.png?branch=master + :target: https://travis-ci.org/PyCQA/pep8 :alt: Build status .. image:: https://pypip.in/wheel/pep8/badge.png?branch=master @@ -88,4 +88,4 @@ Links * `Read the documentation <http://pep8.readthedocs.org/>`_ -* `Fork me on GitHub <http://github.com/jcrocholl/pep8>`_ +* `Fork me on GitHub <http://github.com/PyCQA/pycodestyle>`_ diff --git a/docs/advanced.rst b/docs/advanced.rst index 2bce2e0..62c1b90 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -42,7 +42,7 @@ Skip file header ---------------- Another example is related to the `feature request #143 -<https://github.com/jcrocholl/pep8/issues/143>`_: skip a number of lines +<https://github.com/pycqa/pycodestyle/issues/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:: diff --git a/docs/conf.py b/docs/conf.py index a77ac83..5f990f3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -46,7 +46,7 @@ master_doc = 'index' # General information about the project. project = u'pep8' authors = u'Johann C. Rocholl, Florent Xicluna, Ian Lee' -copyright = u'2006-2014, %s' % (authors) +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 @@ -99,7 +99,11 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +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 diff --git a/docs/developer.rst b/docs/developer.rst index 4725acd..bbafb80 100644 --- a/docs/developer.rst +++ b/docs/developer.rst @@ -11,13 +11,28 @@ Source code The source code is currently `available on GitHub`_ under the terms and conditions of the :ref:`Expat license <license>`. Fork away! -* `Source code <https://github.com/jcrocholl/pep8>`_ and - `issue tracker <https://github.com/jcrocholl/pep8/issues>`_ on GitHub. -* `Continuous tests <http://travis-ci.org/jcrocholl/pep8>`_ against Python +* `Source code <https://github.com/pycqa/pycodestyle>`_ and + `issue tracker <https://github.com/pycqa/pycodestyle/issues>`_ on GitHub. +* `Continuous tests <http://travis-ci.org/pycqa/pep8>`_ against Python 2.6 through 3.4 and PyPy, on `Travis-CI platform <http://about.travis-ci.org/>`_. -.. _available on GitHub: https://github.com/jcrocholl/pep8 +.. _available on GitHub: https://github.com/pycqa/pycodestyle + + +Direction +~~~~~~~~~ + +Some high-level aims and directions to bear in mind for contributions: + +* ``pep8`` is intended to be as fast as possible. + Using the ``ast`` module defeats that purpose. + The `pep8-naming <https://github.com/flintwork/pep8-naming>`_ plugin exists for this sort of functionality. +* If you want to provide extensibility / plugins, + please see `flake8 <https://gitlab.com/pycqa/flake8>`_ - + ``pep8`` doesn't want or need a plugin architecture. +* Python 2.6 support is still deemed important. +* ``pep8`` aims to have no external dependencies. Contribute @@ -86,7 +101,10 @@ Then be sure to pass the tests:: $ python pep8.py --doctest $ python pep8.py --verbose pep8.py +When contributing to pycodestyle, please observe our `Code of Conduct`_. + .. _PEP 8: http://www.python.org/dev/peps/pep-0008/ +.. _Code of Conduct: http://meta.pycqa.org/en/latest/code-of-conduct.html Changes diff --git a/docs/index.rst b/docs/index.rst index 5500e0d..d977022 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,7 +22,7 @@ Contents: developer * Online documentation: http://pep8.readthedocs.org/ -* Source code and issue tracker: https://github.com/jcrocholl/pep8 +* Source code and issue tracker: https://github.com/pycqa/pycodestyle Indices and tables diff --git a/docs/intro.rst b/docs/intro.rst index 006187b..6d1b191 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -47,7 +47,7 @@ the ``pep8`` library: `pep8-naming extension <https://pypi.python.org/pypi/pep8-naming>`_ to use this feature. * **docstring conventions**: they are not in the scope of this library; - see the `pep257 project <https://github.com/GreenSteam/pep257>`_. + see the `pydocstyle project <https://github.com/PyCQA/pydocstyle>`_. * **automatic fixing**: see the section *PEP8 Fixers* in the :ref:`related tools <related-tools>` page. @@ -207,201 +207,202 @@ present (``.pep8`` file is also supported, but it is deprecated). If none of these files have a ``[pep8]`` section, no project specific configuration is loaded. -If the ``ignore`` option is not in the configuration and not in the arguments, -only the error codes ``E123/E133``, ``E226`` and ``E241/E242`` are ignored -(see below). - 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) | -+----------+----------------------------------------------------------------------+ -+----------+----------------------------------------------------------------------+ -| 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 | -+----------+----------------------------------------------------------------------+ -+----------+----------------------------------------------------------------------+ -| **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 | -+----------+----------------------------------------------------------------------+ -+----------+----------------------------------------------------------------------+ -| **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()' | -+----------+----------------------------------------------------------------------+ -| E731 | do not assign a lambda expression, use a def | -+----------+----------------------------------------------------------------------+ -+----------+----------------------------------------------------------------------+ -| **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 | -+----------+----------------------------------------------------------------------+ -+----------+----------------------------------------------------------------------+ -| **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()' | -+----------+----------------------------------------------------------------------+ ++------------+----------------------------------------------------------------------+ +| 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) | ++------------+----------------------------------------------------------------------+ ++------------+----------------------------------------------------------------------+ +| 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 | ++------------+----------------------------------------------------------------------+ ++------------+----------------------------------------------------------------------+ +| **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 | ++------------+----------------------------------------------------------------------+ ++------------+----------------------------------------------------------------------+ +| **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()' | ++------------+----------------------------------------------------------------------+ +| E731 | do not assign a lambda expression, use a def | ++------------+----------------------------------------------------------------------+ ++------------+----------------------------------------------------------------------+ +| **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 occurred before a binary operator | ++------------+----------------------------------------------------------------------+ ++------------+----------------------------------------------------------------------+ +| **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()' | ++------------+----------------------------------------------------------------------+ **(*)** In the default configuration, the checks **E121**, **E123**, **E126**, @@ -430,6 +431,6 @@ The `flake8 checker <https://flake8.readthedocs.org>`_ is a wrapper around ``pep8`` and similar tools. It supports plugins. Other tools which use ``pep8`` are referenced in the Wiki: `list of related -tools <https://github.com/jcrocholl/pep8/wiki/RelatedTools>`_. +tools <https://github.com/pycqa/pycodestyle/wiki/RelatedTools>`_. .. _PEP 8: http://www.python.org/dev/peps/pep-0008/ @@ -2,7 +2,7 @@ # pep8.py - Check Python source code formatting, according to PEP 8 # Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net> # Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com> -# Copyright (C) 2014 Ian Lee <ianlee1521@gmail.com> +# Copyright (C) 2014-2016 Ian Lee <ianlee1521@gmail.com> # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation files @@ -31,7 +31,7 @@ For usage and a list of options, try this: $ python pep8.py -h This program and its regression test suite live here: -http://github.com/jcrocholl/pep8 +https://github.com/pycqa/pycodestyle Groups of errors and warnings: E errors @@ -62,7 +62,7 @@ try: except ImportError: from ConfigParser import RawConfigParser -__version__ = '1.6.2' +__version__ = '1.8.0-dev' DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704' @@ -108,7 +108,7 @@ 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'\b(None|False|True)?\s*([=!]=)' +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' @@ -1172,7 +1172,7 @@ def python_3000_backticks(logical_line): ############################################################################## -if '' == ''.encode(): +if sys.version_info < (3,): # Python 2: implicit encoding. def readlines(filename): """Read the source code.""" @@ -1315,6 +1315,16 @@ if COMMENT_WITH_NL: _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): @@ -1323,13 +1333,13 @@ def register_check(check, codes=None): else: _checks[kind][check] = (codes or [''], args) if inspect.isfunction(check): - args = inspect.getargspec(check)[0] + 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 inspect.getargspec(check.__init__)[0][:2] == ['self', 'tree']: + if _get_parameters(check.__init__)[:2] == ['self', 'tree']: _add_check(check, 'tree', codes, None) @@ -1505,7 +1515,7 @@ class Checker(object): """Build the file's AST and run all AST checks.""" try: tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST) - except (SyntaxError, TypeError): + except (ValueError, SyntaxError, TypeError): return self.report_invalid_syntax() for name, cls, __ in self._ast_checks: checker = cls(tree, self.filename) @@ -1956,8 +1966,8 @@ def get_parser(prog='pep8', version=__version__): parser.add_option('--format', metavar='format', default='default', help="set the error format [default|pylint|<custom>]") parser.add_option('--diff', action='store_true', - help="report only lines changed according to the " - "unified diff received on STDIN") + 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', @@ -1985,24 +1995,24 @@ def read_config(options, args, arglist, parser): 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) - else: - 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) pep8_section = parser.prog if config.has_section(pep8_section): @@ -2075,10 +2085,10 @@ def process_options(arglist=None, parse_argv=False, config_file=None, options = read_config(options, args, arglist, parser) options.reporter = parse_argv and options.quiet == 1 and FileReport - options.filename = options.filename and options.filename.split(',') + options.filename = _parse_multi_options(options.filename) options.exclude = normalize_paths(options.exclude) - options.select = options.select and options.select.split(',') - options.ignore = options.ignore and options.ignore.split(',') + options.select = _parse_multi_options(options.select) + options.ignore = _parse_multi_options(options.ignore) if options.diff: options.reporter = DiffReport @@ -2089,6 +2099,22 @@ def process_options(arglist=None, parse_argv=False, config_file=None, 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 @@ -2101,17 +2127,22 @@ def _main(): pep8style = StyleGuide(parse_argv=True) options = pep8style.options + if options.doctest or options.testsuite: from testsuite.support import run_tests report = run_tests(pep8style) else: report = pep8style.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') diff --git a/testsuite/E71.py b/testsuite/E71.py index ea870e5..7464da9 100644 --- a/testsuite/E71.py +++ b/testsuite/E71.py @@ -10,6 +10,18 @@ if None == res: #: 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 @@ -24,6 +36,12 @@ if True != res: #: E712 if False == res: pass +#: E712 +if res[1] == True: + pass +#: E712 +if res[1] != False: + pass # #: E713 diff --git a/testsuite/test_all.py b/testsuite/test_all.py index 50e2cb9..bfb61d5 100644 --- a/testsuite/test_all.py +++ b/testsuite/test_all.py @@ -46,11 +46,12 @@ class Pep8TestCase(unittest.TestCase): def suite(): - from testsuite import test_api, test_shell, test_util + from testsuite import test_api, test_parser, test_shell, test_util suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(Pep8TestCase)) suite.addTest(unittest.makeSuite(test_api.APITestCase)) + suite.addTest(unittest.makeSuite(test_parser.ParserTestCase)) suite.addTest(unittest.makeSuite(test_shell.ShellTestCase)) suite.addTest(unittest.makeSuite(test_util.UtilTestCase)) return suite diff --git a/testsuite/test_api.py b/testsuite/test_api.py index 341fb34..1cb0d4b 100644 --- a/testsuite/test_api.py +++ b/testsuite/test_api.py @@ -339,6 +339,9 @@ class APITestCase(unittest.TestCase): 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), diff --git a/testsuite/test_parser.py b/testsuite/test_parser.py new file mode 100644 index 0000000..1d9e1ac --- /dev/null +++ b/testsuite/test_parser.py @@ -0,0 +1,61 @@ +import os +import tempfile +import unittest + +import pep8 + + +def _process_file(contents): + with tempfile.NamedTemporaryFile(delete=False) as f: + f.write(contents) + + options, args = pep8.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""" +[pep8] +ignore = E226,E24 + """ + options, args = _process_file(contents) + + self.assertEqual(options.ignore, ["E226", "E24"]) + + def test_multiline_ignore_parsing(self): + contents = b""" +[pep8] +ignore = + E226, + E24 + """ + + options, args = _process_file(contents) + + self.assertEqual(options.ignore, ["E226", "E24"]) + + def test_trailing_comma_ignore_parsing(self): + contents = b""" +[pep8] +ignore = E226, + """ + + options, args = _process_file(contents) + + self.assertEqual(options.ignore, ["E226"]) + + def test_multiline_trailing_comma_ignore_parsing(self): + contents = b""" +[pep8] +ignore = + E226, + E24, + """ + + options, args = _process_file(contents) + + self.assertEqual(options.ignore, ["E226", "E24"]) @@ -1,10 +1,10 @@ -# Tox (http://codespeak.net/~hpk/tox/) is a tool for running tests +# Tox (https://testrun.org/tox/latest/) is a tool for running tests # in multiple virtualenvs. This configuration file will run the # test suite on all supported python versions. To use it, "pip install tox" # and then run "tox" from this directory. [tox] -envlist = py26, py27, py32, py33, py34, pypy, jython +envlist = py26, py27, py32, py33, py34, py35, pypy, pypy3, jython [testenv] commands = |