diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2015-04-25 15:34:13 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2015-04-27 21:18:10 +0200 |
commit | a001b0385412786c50553cfb38c146dfb3646142 (patch) | |
tree | c4bfaf23e826cf036dd66d4f6e46f1e4d23b954d /third_party | |
parent | 0621f07eb482daf7495f6314b0af32853573cb82 (diff) | |
download | samba-a001b0385412786c50553cfb38c146dfb3646142.tar.gz |
pep8: Move to third_party/.
Also, update to latest upstream version.
Signed-Off-By: Jelmer Vernooij <jelmer@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'third_party')
54 files changed, 5446 insertions, 0 deletions
diff --git a/third_party/pep8/.gitignore b/third_party/pep8/.gitignore new file mode 100644 index 00000000000..7eac23f20b5 --- /dev/null +++ b/third_party/pep8/.gitignore @@ -0,0 +1,7 @@ +*.egg +*.egg-info +*.pyc +.tox +dist +docs/_build +build/ diff --git a/third_party/pep8/.travis.yml b/third_party/pep8/.travis.yml new file mode 100644 index 00000000000..b1883254efb --- /dev/null +++ b/third_party/pep8/.travis.yml @@ -0,0 +1,25 @@ +language: python +python: + - 2.6 + - 2.7 + - 3.2 + - 3.3 + - 3.4 + - pypy + - pypy3 +install: + - pip install -e . + - pip list +script: + - python pep8.py --testsuite testsuite + - 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 diff --git a/third_party/pep8/CHANGES.txt b/third_party/pep8/CHANGES.txt new file mode 100644 index 00000000000..91a20950606 --- /dev/null +++ b/third_party/pep8/CHANGES.txt @@ -0,0 +1,651 @@ +Changelog +========= + + +1.x (unreleased) +---------------- + +News: + +* Ian Lee <ianlee1521@gmail.com> 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) + +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) + + +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 to change 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 to construct 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 http://pep8.readthedocs.org/. (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 to specify ``--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. diff --git a/third_party/pep8/LICENSE b/third_party/pep8/LICENSE new file mode 100644 index 00000000000..70242b8101c --- /dev/null +++ b/third_party/pep8/LICENSE @@ -0,0 +1,24 @@ +Copyright © 2006-2009 Johann C. Rocholl <johann@rocholl.net> +Copyright © 2009-2014 Florent Xicluna <florent.xicluna@gmail.com> + +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. diff --git a/third_party/pep8/MANIFEST.in b/third_party/pep8/MANIFEST.in new file mode 100644 index 00000000000..4532c06d531 --- /dev/null +++ b/third_party/pep8/MANIFEST.in @@ -0,0 +1,9 @@ +include *.txt +include *.rst +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 diff --git a/third_party/pep8/Makefile b/third_party/pep8/Makefile new file mode 100644 index 00000000000..29b243d4c5e --- /dev/null +++ b/third_party/pep8/Makefile @@ -0,0 +1,13 @@ +test : + python pep8.py --testsuite testsuite + +selftest : + python pep8.py --statistics pep8.py + +doctest : + python pep8.py --doctest + +unittest : + python -m testsuite.test_all + +alltest : test selftest doctest unittest diff --git a/third_party/pep8/README.rst b/third_party/pep8/README.rst new file mode 100644 index 00000000000..d842f05829f --- /dev/null +++ b/third_party/pep8/README.rst @@ -0,0 +1,91 @@ +pep8 - Python style guide checker +================================= + +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/ + + +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 pep8.py file for this purpose. + +* Comes with a comprehensive test suite. + +Installation +------------ + +You can install, upgrade, uninstall pep8.py with these commands:: + + $ pip install pep8 + $ pip install --upgrade pep8 + $ pip uninstall pep8 + +There's also a package for Debian/Ubuntu, but it's not always the +latest version. + +Example usage and output +------------------------ + +:: + + $ pep8 --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 pep8.py show the source code for each error, and +even the relevant text from PEP 8:: + + $ pep8 --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:: + + $ pep8 --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 +----- + +.. image:: https://api.travis-ci.org/jcrocholl/pep8.png?branch=master + :target: https://travis-ci.org/jcrocholl/pep8 + :alt: Build status + +.. image:: https://pypip.in/wheel/pep8/badge.png?branch=master + :target: https://pypi.python.org/pypi/pep8 + :alt: Wheel Status + +* `Read the documentation <http://pep8.readthedocs.org/>`_ + +* `Fork me on GitHub <http://github.com/jcrocholl/pep8>`_ diff --git a/third_party/pep8/docs/Makefile b/third_party/pep8/docs/Makefile new file mode 100644 index 00000000000..1952db44b10 --- /dev/null +++ b/third_party/pep8/docs/Makefile @@ -0,0 +1,153 @@ +# 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 <target>' where <target> 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/pep8.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pep8.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/pep8" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pep8" + @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." diff --git a/third_party/pep8/docs/advanced.rst b/third_party/pep8/docs/advanced.rst new file mode 100644 index 00000000000..2bce2e04e80 --- /dev/null +++ b/third_party/pep8/docs/advanced.rst @@ -0,0 +1,77 @@ +.. currentmodule:: pep8 + +============== +Advanced usage +============== + + +Automated tests +--------------- + +You can also execute `pep8` tests from Python code. For example, this +can be highly useful for automated testing of coding style conformance +in your project:: + + import unittest + import pep8 + + + class TestCodeFormat(unittest.TestCase): + + def test_pep8_conformance(self): + """Test that we conform to PEP8.""" + pep8style = pep8.StyleGuide(quiet=True) + result = pep8style.check_files(['file1.py', 'file2.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + +If you are using `nosetests` for running tests, remove `quiet=True` +since Nose suppresses stdout. + +There's also a shortcut for checking a single file:: + + import pep8 + + fchecker = pep8.Checker('testsuite/E27.py', show_source=True) + file_errors = fchecker.check_all() + + print("Found %s errors (and warnings)" % file_errors) + + +Skip file header +---------------- + +Another example is related to the `feature request #143 +<https://github.com/jcrocholl/pep8/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:: + + #!python + import pep8 + + LINES_SLICE = slice(14, -20) + + class PEP8(pep8.StyleGuide): + """This subclass of pep8.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 = pep8.readlines(filename)[LINES_SLICE] + return super(PEP8, self).input_file( + filename, lines=lines, expected=expected, line_offset=line_offset) + + if __name__ == '__main__': + pep8style = PEP8(parse_argv=True, config_file=True) + report = pep8style.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 ``pep8``. diff --git a/third_party/pep8/docs/api.rst b/third_party/pep8/docs/api.rst new file mode 100644 index 00000000000..b346abab01a --- /dev/null +++ b/third_party/pep8/docs/api.rst @@ -0,0 +1,88 @@ +======== +pep8 API +======== + +.. module:: pep8 + +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='pep8', version=pep8.__version__) + .. autofunction:: init_checks_registry() diff --git a/third_party/pep8/docs/conf.py b/third_party/pep8/docs/conf.py new file mode 100644 index 00000000000..a77ac8386d2 --- /dev/null +++ b/third_party/pep8/docs/conf.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +# +# pep8 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'pep8' +authors = u'Johann C. Rocholl, Florent Xicluna, Ian Lee' +copyright = u'2006-2014, %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. +# + +pep8_version = __import__('pep8').__version__.split('.') +# The short X.Y version. +version = '.'.join(pep8_version[:2]) +# The full version, including alpha/beta/rc tags. +release = '.'.join(pep8_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. +html_theme = 'default' + +# 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 +# "<project> v<release> 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 <link> 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 = 'pep8doc' + + +# -- 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', 'pep8.tex', u'pep8 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', 'pep8', u'pep8 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', 'pep8', u'pep8 documentation', authors, + 'pep8', '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' diff --git a/third_party/pep8/docs/developer.rst b/third_party/pep8/docs/developer.rst new file mode 100644 index 00000000000..4725acd9e7c --- /dev/null +++ b/third_party/pep8/docs/developer.rst @@ -0,0 +1,96 @@ +.. currentmodule:: pep8 + +================= +Developer's notes +================= + + +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 + 2.6 through 3.4 and PyPy, on `Travis-CI platform + <http://about.travis-ci.org/>`_. + +.. _available on GitHub: https://github.com/jcrocholl/pep8 + + +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 pep8.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 pep8.py --testsuite testsuite + $ python pep8.py --doctest + $ python pep8.py --verbose pep8.py + +.. _PEP 8: http://www.python.org/dev/peps/pep-0008/ + + +Changes +~~~~~~~ + +.. include:: ../CHANGES.txt + :start-line: 3 diff --git a/third_party/pep8/docs/index.rst b/third_party/pep8/docs/index.rst new file mode 100644 index 00000000000..5500e0dc49e --- /dev/null +++ b/third_party/pep8/docs/index.rst @@ -0,0 +1,69 @@ +.. pep8 documentation master file + +pep8's documentation +==================== + +*Python style guide checker* + +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 <api> + developer + +* Online documentation: http://pep8.readthedocs.org/ +* Source code and issue tracker: https://github.com/jcrocholl/pep8 + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` + + +Credits +======= + +Created by Johann C. Rocholl. + +Maintained by Florent Xicluna and Ian Lee. + + +.. _license: + +License +======= + +The ``pep8`` 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. diff --git a/third_party/pep8/docs/intro.rst b/third_party/pep8/docs/intro.rst new file mode 100644 index 00000000000..13a955397e1 --- /dev/null +++ b/third_party/pep8/docs/intro.rst @@ -0,0 +1,435 @@ +.. currentmodule:: pep8 + +Introduction +============ + +pep8 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 pep8.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 ``pep8`` library: + +* **naming conventions**: this kind of feature is supported through plugins. + Install `flake8 <https://pypi.python.org/pypi/flake8>`_ and the + `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>`_. +* **automatic fixing**: see the section *PEP8 Fixers* in the + :ref:`related tools <related-tools>` page. + + +Installation +------------ + +You can install, upgrade, uninstall pep8.py with these commands:: + + $ pip install pep8 + $ pip install --upgrade pep8 + $ pip uninstall pep8 + +There's also a package for Debian/Ubuntu, but it's not always the +latest version:: + + $ sudo apt-get install pep8 + + +Example usage and output +------------------------ + +:: + + $ pep8 --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 pep8.py show the source code for each error, and +even the relevant text from PEP 8:: + + $ pep8 --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:: + + $ pep8 --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 pep8.py show the error text in different formats by using --format having options default/pylint/custom:: + + $ pep8 testsuite/E40.py --format=default + testsuite/E40.py:2:10: E401 multiple imports on one line + + $ pep8 testsuite/E40.py --format=pylint + testsuite/E40.py:2: [E401] multiple imports on one line + + $ pep8 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:: + + $ pep8 -h + Usage: pep8 [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) + --hang-closing hang closing bracket instead of matching indentation of + opening bracket's line + --format=format set the error format [default|pylint|<custom>] + --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 [pep8] 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, hang-closing, count, format, quiet, show-pep8, + show-source, statistics, verbose. + + --config=path user config file location (default: ~/.config/pep8) + + +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: + ``~\.pep8`` + +Otherwise, if the :envvar:`XDG_CONFIG_HOME` environment variable is defined: + ``XDG_CONFIG_HOME/pep8`` + +Else if :envvar:`XDG_CONFIG_HOME` is not defined: + ``~/.config/pep8`` + +Example:: + + [pep8] + ignore = E226,E302,E41 + max-line-length = 160 + +At the project level, a ``setup.cfg`` file or a ``tox.ini`` file is read if +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()' | ++----------+----------------------------------------------------------------------+ + + +**(*)** In the default configuration, the checks **E121**, **E123**, **E126**, +**E133**, **E226**, **E241**, **E242** and **E704** are ignored because they +are not rules unanimously accepted, and `PEP 8`_ does not enforce them. The +check **E133** is mutually exclusive with check **E123**. Use switch ``--hang- +closing`` to report **E133** instead of **E123**. + +**(^)** 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 pep8.py --first --select E,W testsuite/ --format '%(code)s: %(text)s' + + +.. _related-tools: + +Related tools +------------- + +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>`_. + +.. _PEP 8: http://www.python.org/dev/peps/pep-0008/ diff --git a/third_party/pep8/docs/make.bat b/third_party/pep8/docs/make.bat new file mode 100644 index 00000000000..efa0e94de4f --- /dev/null +++ b/third_party/pep8/docs/make.bat @@ -0,0 +1,190 @@ +@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 ^<target^>` where ^<target^> 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\pep8.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pep8.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 diff --git a/third_party/pep8/setup.cfg b/third_party/pep8/setup.cfg new file mode 100644 index 00000000000..65ca96deea8 --- /dev/null +++ b/third_party/pep8/setup.cfg @@ -0,0 +1,7 @@ +[wheel] +universal = 1 + +[pep8] +select = +ignore = E226,E24 +max_line_length = 79 diff --git a/third_party/pep8/setup.py b/third_party/pep8/setup.py new file mode 100644 index 00000000000..29182c6d6f9 --- /dev/null +++ b/third_party/pep8/setup.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +from __future__ import with_statement +from setuptools import setup + + +def get_version(): + with open('pep8.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='pep8', + version=get_version(), + description="Python style guide checker", + long_description=get_long_description(), + keywords='pep8', + author='Johann C. Rocholl', + author_email='johann@rocholl.net', + url='http://pep8.readthedocs.org/', + license='Expat license', + py_modules=['pep8'], + namespace_packages=[], + include_package_data=True, + zip_safe=False, + install_requires=[ + # Broken with Python 3: https://github.com/pypa/pip/issues/650 + # 'setuptools', + ], + entry_points={ + 'console_scripts': [ + 'pep8 = pep8:_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 :: 3', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], + test_suite='testsuite.test_all.suite', +) diff --git a/third_party/pep8/testsuite/E10.py b/third_party/pep8/testsuite/E10.py new file mode 100644 index 00000000000..cd142e39333 --- /dev/null +++ b/third_party/pep8/testsuite/E10.py @@ -0,0 +1,41 @@ +#: E101 W191 +for a in 'abc': + for b in 'xyz': + print a # indented with 8 spaces + print b # indented with 1 tab +#: E101 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 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', + ]) +#: diff --git a/third_party/pep8/testsuite/E11.py b/third_party/pep8/testsuite/E11.py new file mode 100644 index 00000000000..4ed1096334a --- /dev/null +++ b/third_party/pep8/testsuite/E11.py @@ -0,0 +1,36 @@ +#: E111 +if x > 2: + print x +#: E111 +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() diff --git a/third_party/pep8/testsuite/E12.py b/third_party/pep8/testsuite/E12.py new file mode 100644 index 00000000000..7d76ee37a54 --- /dev/null +++ b/third_party/pep8/testsuite/E12.py @@ -0,0 +1,376 @@ +#: 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 +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 +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 +if ( + x == ( + 3 + ) or + y == 4): + pass +#: E126 +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 +rv.update(d=('a' + 'b', 'c'), + e=42, f=42 + + 42) +#: E127 +input1 = {'a': {'calc': 1 + 2}, 'b': 1 + + 42} +#: E128 +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=' ') +#: diff --git a/third_party/pep8/testsuite/E12not.py b/third_party/pep8/testsuite/E12not.py new file mode 100644 index 00000000000..e76ef13433a --- /dev/null +++ b/third_party/pep8/testsuite/E12not.py @@ -0,0 +1,644 @@ +if ( + 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 + + +if (foo == bar and + baz == frop): + pass + +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' + +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) + +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" + ) +# +# you want vertical alignment, so use a parens +if ((foo.bar("baz") and + foo.bar("frop") + )): + print "yes" + +# also ok, but starting to look like LISP +if ((foo.bar("baz") and + foo.bar("frop"))): + print "yes" + +if (a == 2 or + b == "abc def ghi" + "jkl mno"): + return True + +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])) + + +if os.path.exists(os.path.join(path, PEP8_BIN)): + cmd = ([os.path.join(path, PEP8_BIN)] + + self._pep8_options(targetfile)) + + +fixed = (re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] + + target[c + 1:]) + +fixed = ( + re.sub(r'\t+', ' ', target[c::-1], 1)[::-1] + + target[c + 1:] +) + + +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('^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' + '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' + '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' + '(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 <br> too.""" + return unicode((s or '').replace('&', '&') + .replace('>', '>') + .replace('<', '<') + .replace("'", ''') + .replace('"', '"') + .replace('\n', '<br>\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 + ) +) diff --git a/third_party/pep8/testsuite/E20.py b/third_party/pep8/testsuite/E20.py new file mode 100644 index 00000000000..2f1ecc28c92 --- /dev/null +++ b/third_party/pep8/testsuite/E20.py @@ -0,0 +1,55 @@ +#: 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] +#: diff --git a/third_party/pep8/testsuite/E21.py b/third_party/pep8/testsuite/E21.py new file mode 100644 index 00000000000..96b55b87901 --- /dev/null +++ b/third_party/pep8/testsuite/E21.py @@ -0,0 +1,14 @@ +#: 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 diff --git a/third_party/pep8/testsuite/E22.py b/third_party/pep8/testsuite/E22.py new file mode 100644 index 00000000000..9d8efda5e67 --- /dev/null +++ b/third_party/pep8/testsuite/E22.py @@ -0,0 +1,157 @@ +#: 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", +} +#: diff --git a/third_party/pep8/testsuite/E23.py b/third_party/pep8/testsuite/E23.py new file mode 100644 index 00000000000..e561fe795f9 --- /dev/null +++ b/third_party/pep8/testsuite/E23.py @@ -0,0 +1,15 @@ +#: E231 +a = (1,2) +#: E231 +a[b1,:] +#: E231 +a = [{'a':''}] +#: Okay +a = (4,) +b = (5, ) +c = {'text': text[5:]} + +result = { + 'key1': 'value', + 'key2': 'value', +} diff --git a/third_party/pep8/testsuite/E24.py b/third_party/pep8/testsuite/E24.py new file mode 100644 index 00000000000..36fb4aa7ebe --- /dev/null +++ b/third_party/pep8/testsuite/E24.py @@ -0,0 +1,13 @@ +#: 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] diff --git a/third_party/pep8/testsuite/E25.py b/third_party/pep8/testsuite/E25.py new file mode 100644 index 00000000000..ad8db8822e1 --- /dev/null +++ b/third_party/pep8/testsuite/E25.py @@ -0,0 +1,36 @@ +#: 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) -> AnyStr: + pass diff --git a/third_party/pep8/testsuite/E26.py b/third_party/pep8/testsuite/E26.py new file mode 100644 index 00000000000..e64012620a8 --- /dev/null +++ b/third_party/pep8/testsuite/E26.py @@ -0,0 +1,59 @@ +#: 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 ########################## # + # ####################################################################### # diff --git a/third_party/pep8/testsuite/E27.py b/third_party/pep8/testsuite/E27.py new file mode 100644 index 00000000000..f9d3e8e17cb --- /dev/null +++ b/third_party/pep8/testsuite/E27.py @@ -0,0 +1,30 @@ +#: 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 diff --git a/third_party/pep8/testsuite/E30.py b/third_party/pep8/testsuite/E30.py new file mode 100644 index 00000000000..d2d7bf35625 --- /dev/null +++ b/third_party/pep8/testsuite/E30.py @@ -0,0 +1,90 @@ +#: 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 +#: + + +#: 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) +""" +#: diff --git a/third_party/pep8/testsuite/E30not.py b/third_party/pep8/testsuite/E30not.py new file mode 100644 index 00000000000..0fd8fb0c448 --- /dev/null +++ b/third_party/pep8/testsuite/E30not.py @@ -0,0 +1,134 @@ +#: 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 diff --git a/third_party/pep8/testsuite/E40.py b/third_party/pep8/testsuite/E40.py new file mode 100644 index 00000000000..1051e32cf8e --- /dev/null +++ b/third_party/pep8/testsuite/E40.py @@ -0,0 +1,38 @@ +#: 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 +#: E402 +__all__ = ['abc'] + +import foo +#: Okay +try: + import foo +except: + 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 diff --git a/third_party/pep8/testsuite/E50.py b/third_party/pep8/testsuite/E50.py new file mode 100644 index 00000000000..f60f3890e7b --- /dev/null +++ b/third_party/pep8/testsuite/E50.py @@ -0,0 +1,118 @@ +#: 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 +'''multiline string +with a long long long long long long long long long long long long long long long long line +''' +#: E501 +'''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 +""" +longnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaceslongnospaces""" +#: Okay +""" +This + almost_empty_line +""" +#: E501 +""" +This + almost_empty_line +""" +#: E501 +# 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 +# This +# almost_empty_line diff --git a/third_party/pep8/testsuite/E70.py b/third_party/pep8/testsuite/E70.py new file mode 100644 index 00000000000..85ca66688f0 --- /dev/null +++ b/third_party/pep8/testsuite/E70.py @@ -0,0 +1,20 @@ +#: 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 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 +#: diff --git a/third_party/pep8/testsuite/E71.py b/third_party/pep8/testsuite/E71.py new file mode 100644 index 00000000000..ea870e54120 --- /dev/null +++ b/third_party/pep8/testsuite/E71.py @@ -0,0 +1,73 @@ +#: E711 +if res == None: + pass +#: E711 +if res != None: + pass +#: E711 +if None == res: + pass +#: E711 +if None != res: + pass + +# +#: E712 +if res == True: + pass +#: E712 +if res != False: + pass +#: E712 +if True != res: + pass +#: E712 +if False == res: + 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 +#: diff --git a/third_party/pep8/testsuite/E72.py b/third_party/pep8/testsuite/E72.py new file mode 100644 index 00000000000..8eb34cb3991 --- /dev/null +++ b/third_party/pep8/testsuite/E72.py @@ -0,0 +1,51 @@ +#: 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 diff --git a/third_party/pep8/testsuite/E73.py b/third_party/pep8/testsuite/E73.py new file mode 100644 index 00000000000..60fcd239088 --- /dev/null +++ b/third_party/pep8/testsuite/E73.py @@ -0,0 +1,18 @@ +#: 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' diff --git a/third_party/pep8/testsuite/E90.py b/third_party/pep8/testsuite/E90.py new file mode 100644 index 00000000000..3111c6833fe --- /dev/null +++ b/third_party/pep8/testsuite/E90.py @@ -0,0 +1,26 @@ +#: E901 +} +#: E901 += [x +#: E901 E101 W191 +while True: + try: + pass + except: + print 'Whoops' +#: E122 E225 E251 E251 E701 + +# 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 +#: diff --git a/third_party/pep8/testsuite/W19.py b/third_party/pep8/testsuite/W19.py new file mode 100644 index 00000000000..69db3065dbb --- /dev/null +++ b/third_party/pep8/testsuite/W19.py @@ -0,0 +1,145 @@ +#: W191 +if False: + print # indented with 1 tab +#: + + +#: W191 +y = x == 2 \ + or x == 3 +#: E101 W191 +if ( + x == ( + 3 + ) or + y == 4): + pass +#: E101 W191 +if x == 2 \ + or y > 1 \ + or x == 3: + pass +#: E101 W191 +if x == 2 \ + or y > 1 \ + or x == 3: + pass +#: + +#: E101 W191 +if (foo == bar and + baz == frop): + pass +#: E101 W191 +if ( + foo == bar and + baz == frop +): + pass +#: + +#: 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 W191 + + +def long_function_name( + var_one, var_two, var_three, + var_four): + print(var_one) +#: E101 W191 +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 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 W191 +# you want vertical alignment, so use a parens +if ((foo.bar("baz") and + foo.bar("frop") + )): + print "yes" +#: E101 W191 +# also ok, but starting to look like LISP +if ((foo.bar("baz") and + foo.bar("frop"))): + print "yes" +#: E101 W191 +if (a == 2 or + b == "abc def ghi" + "jkl mno"): + return True +#: E101 W191 +if (a == 2 or + b == """abc def ghi +jkl mno"""): + return True +#: 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 W191 W191 +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 W191 +if foo is None and bar is "frop" and \ + blah == 'yeah': + blah = 'yeahnah' + + +# +#: W191 W191 W191 +if True: + foo( + 1, + 2) +#: 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' +] +#: diff --git a/third_party/pep8/testsuite/W29.py b/third_party/pep8/testsuite/W29.py new file mode 100644 index 00000000000..1cdd84ff58d --- /dev/null +++ b/third_party/pep8/testsuite/W29.py @@ -0,0 +1,21 @@ +#: 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' diff --git a/third_party/pep8/testsuite/W39.py b/third_party/pep8/testsuite/W39.py new file mode 100644 index 00000000000..d4fe0a42f26 --- /dev/null +++ b/third_party/pep8/testsuite/W39.py @@ -0,0 +1,18 @@ +#: 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 +''' diff --git a/third_party/pep8/testsuite/W60.py b/third_party/pep8/testsuite/W60.py new file mode 100644 index 00000000000..973d22ff9e9 --- /dev/null +++ b/third_party/pep8/testsuite/W60.py @@ -0,0 +1,15 @@ +#: 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` diff --git a/third_party/pep8/testsuite/__init__.py b/third_party/pep8/testsuite/__init__.py new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/third_party/pep8/testsuite/__init__.py diff --git a/third_party/pep8/testsuite/latin-1.py b/third_party/pep8/testsuite/latin-1.py new file mode 100644 index 00000000000..8328cfba9e7 --- /dev/null +++ b/third_party/pep8/testsuite/latin-1.py @@ -0,0 +1,6 @@ +# -*- coding: latin-1 -*- +# Test non-UTF8 encoding +latin1 = ('' + '') + +c = ("w") diff --git a/third_party/pep8/testsuite/noqa.py b/third_party/pep8/testsuite/noqa.py new file mode 100644 index 00000000000..02fdd4f8251 --- /dev/null +++ b/third_party/pep8/testsuite/noqa.py @@ -0,0 +1,15 @@ +#: 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 +#: diff --git a/third_party/pep8/testsuite/python3.py b/third_party/pep8/testsuite/python3.py new file mode 100644 index 00000000000..888188006f6 --- /dev/null +++ b/third_party/pep8/testsuite/python3.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + + +# Annotated function (Issue #29) +def foo(x: int) -> int: + return x + 1 diff --git a/third_party/pep8/testsuite/support.py b/third_party/pep8/testsuite/support.py new file mode 100644 index 00000000000..5185005750c --- /dev/null +++ b/third_party/pep8/testsuite/support.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +import os.path +import re +import sys + +from pep8 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) + + +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.") + + +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("pep8.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.""" + 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() + +# nose should not collect these functions +init_tests.__test__ = run_tests.__test__ = False diff --git a/third_party/pep8/testsuite/test_all.py b/third_party/pep8/testsuite/test_all.py new file mode 100644 index 00000000000..50e2cb9fbde --- /dev/null +++ b/third_party/pep8/testsuite/test_all.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import os.path +import sys +import unittest + +import pep8 +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 Pep8TestCase(unittest.TestCase): + """Test the standard errors and warnings (E and W).""" + + def setUp(self): + self._style = pep8.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(pep8, 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 = [pep8.__file__.rstrip('oc'), __file__.rstrip('oc'), + os.path.join(ROOT_DIR, 'setup.py')] + report = self._style.init_report(pep8.StandardReport) + report = self._style.check_files(files) + self.assertFalse(report.total_errors, + msg='Failures: %s' % report.messages) + + +def suite(): + from testsuite import test_api, test_shell, test_util + + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(Pep8TestCase)) + suite.addTest(unittest.makeSuite(test_api.APITestCase)) + 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 --git a/third_party/pep8/testsuite/test_api.py b/third_party/pep8/testsuite/test_api.py new file mode 100644 index 00000000000..341fb34bbf9 --- /dev/null +++ b/third_party/pep8/testsuite/test_api.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +import os.path +import shlex +import sys +import unittest + +import pep8 +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 = pep8._checks + sys.stdout = PseudoFile() + sys.stderr = PseudoFile() + pep8._checks = dict((k, dict((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 + pep8._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 + pep8.register_check(check_dummy, ['Z001']) + + self.assertTrue(check_dummy in pep8._checks['physical_line']) + codes, args = pep8._checks['physical_line'][check_dummy] + self.assertTrue('Z001' in codes) + self.assertEqual(args, ['physical_line', 'line_number']) + + options = pep8.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 + pep8.register_check(check_dummy, ['Z401']) + + self.assertTrue(check_dummy in pep8._checks['logical_line']) + codes, args = pep8._checks['logical_line'][check_dummy] + self.assertTrue('Z401' in codes) + self.assertEqual(args, ['logical_line', 'tokens']) + + pep8.register_check(check_dummy, []) + pep8.register_check(check_dummy, ['Z402', 'Z403']) + codes, args = pep8._checks['logical_line'][check_dummy] + self.assertEqual(codes, ['Z401', 'Z402', 'Z403']) + self.assertEqual(args, ['logical_line', 'tokens']) + + options = pep8.StyleGuide().options + self.assertTrue(any(func == check_dummy + for name, func, args in options.logical_checks)) + + def test_register_ast_check(self): + pep8.register_check(DummyChecker, ['Z701']) + + self.assertTrue(DummyChecker in pep8._checks['tree']) + codes, args = pep8._checks['tree'][DummyChecker] + self.assertTrue('Z701' in codes) + self.assertTrue(args is None) + + options = pep8.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 + pep8.register_check(InvalidChecker, ['Z741']) + pep8.register_check(check_dummy, ['Z441']) + + for checkers in pep8._checks.values(): + self.assertTrue(DummyChecker not in checkers) + self.assertTrue(check_dummy not in checkers) + + self.assertRaises(TypeError, pep8.register_check) + + def test_styleguide(self): + report = pep8.StyleGuide().check_files() + self.assertEqual(report.total_errors, 0) + self.assertFalse(sys.stdout) + self.assertFalse(sys.stderr) + self.reset() + + report = pep8.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 = pep8.StyleGuide().check_files([E11]) + stdout = sys.stdout.getvalue().splitlines() + self.assertEqual(len(stdout), report.total_errors) + self.assertEqual(report.total_errors, 17) + self.assertFalse(sys.stderr) + self.reset() + + # Passing the paths in the constructor gives same result + report = pep8.StyleGuide(paths=[E11]).check_files() + stdout = sys.stdout.getvalue().splitlines() + self.assertEqual(len(stdout), report.total_errors) + self.assertEqual(report.total_errors, 17) + self.assertFalse(sys.stderr) + self.reset() + + def test_styleguide_options(self): + # Instanciate a simple checker + pep8style = pep8.StyleGuide(paths=[E11]) + + # Check style's attributes + self.assertEqual(pep8style.checker_class, pep8.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')) + 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('pep8 %s /dev/null' % argstring) + try: + return pep8.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') + ) + + 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, ('',)) + + pep8style = pep8.StyleGuide(paths=[E11]) + self.assertFalse(pep8style.ignore_code('E112')) + self.assertFalse(pep8style.ignore_code('W191')) + self.assertTrue(pep8style.ignore_code('E241')) + + pep8style = pep8.StyleGuide(select='E', paths=[E11]) + self.assertFalse(pep8style.ignore_code('E112')) + self.assertTrue(pep8style.ignore_code('W191')) + self.assertFalse(pep8style.ignore_code('E241')) + + pep8style = pep8.StyleGuide(select='W', paths=[E11]) + self.assertTrue(pep8style.ignore_code('E112')) + self.assertFalse(pep8style.ignore_code('W191')) + self.assertTrue(pep8style.ignore_code('E241')) + + pep8style = pep8.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 = pep8.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 = pep8.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 = pep8.StyleGuide().options + self.assertTrue(any(func == pep8.indentation + for name, func, args in options.logical_checks)) + options = pep8.StyleGuide(select=['E']).options + self.assertTrue(any(func == pep8.indentation + for name, func, args in options.logical_checks)) + options = pep8.StyleGuide(ignore=['W']).options + self.assertTrue(any(func == pep8.indentation + for name, func, args in options.logical_checks)) + options = pep8.StyleGuide(ignore=['E12']).options + self.assertTrue(any(func == pep8.indentation + for name, func, args in options.logical_checks)) + + # Do not run E11 checks + options = pep8.StyleGuide(select=['W']).options + self.assertFalse(any(func == pep8.indentation + for name, func, args in options.logical_checks)) + options = pep8.StyleGuide(ignore=['E']).options + self.assertFalse(any(func == pep8.indentation + for name, func, args in options.logical_checks)) + options = pep8.StyleGuide(ignore=['E11']).options + self.assertFalse(any(func == pep8.indentation + for name, func, args in options.logical_checks)) + + def test_styleguide_init_report(self): + pep8style = pep8.StyleGuide(paths=[E11]) + + self.assertEqual(pep8style.options.reporter, pep8.StandardReport) + self.assertEqual(type(pep8style.options.report), pep8.StandardReport) + + class MinorityReport(pep8.BaseReport): + pass + + report = pep8style.init_report(MinorityReport) + self.assertEqual(pep8style.options.report, report) + self.assertEqual(type(report), MinorityReport) + + pep8style = pep8.StyleGuide(paths=[E11], reporter=MinorityReport) + self.assertEqual(type(pep8style.options.report), MinorityReport) + self.assertEqual(pep8style.options.reporter, MinorityReport) + + def test_styleguide_check_files(self): + pep8style = pep8.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) + pep8.register_check(DummyChecker, ['Z701']) + source = '#\n' + if hasattr(source, 'decode'): + source = source.decode('ascii') + + pep8style = pep8.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): + pep8.register_check(DummyChecker, ['Z701']) + + pep8style = pep8.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" + 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): + pep8.register_check(DummyChecker, ['Z701']) + lines = [ + 'def foo():\n', + ' """test docstring""\'\n', + ] + + pep8style = pep8.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): + pep8.register_check(DummyChecker, ['Z701']) + lines = [ + 'def foo():\n', + ' pass\n', + '\n', + '\\\n', + '\n', + 'def bar():\n', + ' pass\n', + ] + + pep8style = pep8.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 diff --git a/third_party/pep8/testsuite/test_shell.py b/third_party/pep8/testsuite/test_shell.py new file mode 100644 index 00000000000..e536852f1b8 --- /dev/null +++ b/third_party/pep8/testsuite/test_shell.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +import os.path +import sys +import unittest + +import pep8 +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 = pep8.PROJECT_CONFIG + self._saved_cpread = pep8.RawConfigParser._read + self._saved_stdin_get_value = pep8.stdin_get_value + self._config_filenames = [] + self.stdin = '' + sys.argv = ['pep8'] + sys.stdout = PseudoFile() + sys.stderr = PseudoFile() + + def fake_config_parser_read(cp, fp, filename): + self._config_filenames.append(filename) + pep8.RawConfigParser._read = fake_config_parser_read + pep8.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 + pep8.PROJECT_CONFIG = self._saved_pconfig + pep8.RawConfigParser._read = self._saved_cpread + pep8.stdin_get_value = self._saved_stdin_get_value + + def stdin_get_value(self): + return self.stdin + + def pep8(self, *args): + del sys.stdout[:], sys.stderr[:] + sys.argv[1:] = args + try: + pep8._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.pep8('--help') + self.assertFalse(errcode) + self.assertFalse(stderr) + self.assertTrue(stdout.startswith("Usage: pep8 [options] input")) + + stdout, stderr, errcode = self.pep8('--version') + self.assertFalse(errcode) + self.assertFalse(stderr) + self.assertEqual(stdout.count('\n'), 1) + + stdout, stderr, errcode = self.pep8('--obfuscated') + self.assertEqual(errcode, 2) + self.assertEqual(stderr.splitlines(), + ["Usage: pep8 [options] input ...", "", + "pep8: 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.pep8(E11) + stdout = stdout.splitlines() + self.assertEqual(errcode, 1) + self.assertFalse(stderr) + self.assertEqual(len(stdout), 17) + for line, num, col in zip(stdout, (3, 6, 9, 12), (3, 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 pep8'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): + pep8.PROJECT_CONFIG = () + stdout, stderr, errcode = self.pep8('-') + self.assertFalse(errcode) + self.assertFalse(stderr) + self.assertFalse(stdout) + + self.stdin = 'import os, sys\n' + stdout, stderr, errcode = self.pep8('-') + 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.pep8('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 + pep8.PROJECT_CONFIG = () + stdout, stderr, errcode = self.pep8() + self.assertEqual(errcode, 2) + self.assertEqual(stderr.splitlines(), + ["Usage: pep8 [options] input ...", "", + "pep8: error: input not specified"]) + self.assertFalse(self._config_filenames) + + def test_check_diff(self): + pep8.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.pep8('--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.pep8('--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.pep8('--diff') + (stdout,) = stdout.splitlines() + self.assertEqual(errcode, 1) + self.assertFalse(stderr) + self.assertTrue('testsuite/E11.py:6:6: E111 ' in stdout) + + # missing '--diff' + self.stdin = '\n'.join(diff_lines) + stdout, stderr, errcode = self.pep8() + self.assertEqual(errcode, 2) + self.assertFalse(stdout) + self.assertTrue(stderr.startswith('Usage: pep8 [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.pep8('--diff') + self.assertFalse(errcode) + self.assertFalse(stdout) + self.assertFalse(stderr) diff --git a/third_party/pep8/testsuite/test_util.py b/third_party/pep8/testsuite/test_util.py new file mode 100644 index 00000000000..11395ccaa3d --- /dev/null +++ b/third_party/pep8/testsuite/test_util.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import os +import unittest + +import pep8 + + +class UtilTestCase(unittest.TestCase): + def test_normalize_paths(self): + cwd = os.getcwd() + + self.assertEqual(pep8.normalize_paths(''), []) + self.assertEqual(pep8.normalize_paths([]), []) + self.assertEqual(pep8.normalize_paths(None), []) + self.assertEqual(pep8.normalize_paths(['foo']), ['foo']) + self.assertEqual(pep8.normalize_paths('foo'), ['foo']) + self.assertEqual(pep8.normalize_paths('foo,bar'), ['foo', 'bar']) + self.assertEqual(pep8.normalize_paths('foo, bar '), ['foo', 'bar']) + self.assertEqual(pep8.normalize_paths('/foo/bar,baz/../bat'), + ['/foo/bar', cwd + '/bat']) + self.assertEqual(pep8.normalize_paths(".pyc,\n build/*"), + ['.pyc', cwd + '/build/*']) diff --git a/third_party/pep8/testsuite/utf-8-bom.py b/third_party/pep8/testsuite/utf-8-bom.py new file mode 100644 index 00000000000..9c065c9494e --- /dev/null +++ b/third_party/pep8/testsuite/utf-8-bom.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +hello = 'こんにちわ' + +# EOF diff --git a/third_party/pep8/testsuite/utf-8.py b/third_party/pep8/testsuite/utf-8.py new file mode 100644 index 00000000000..2cee57942f8 --- /dev/null +++ b/third_party/pep8/testsuite/utf-8.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + + +class Rectangle(Blob): + + def __init__(self, width, height, + color='black', emphasis=None, highlight=0): + if width == 0 and height == 0 and \ + color == 'red' and emphasis == 'strong' or \ + highlight > 100: + raise ValueError("sorry, you lose") + if width == 0 and height == 0 and (color == 'red' or + emphasis is None): + raise ValueError("I don't think so -- values are %s, %s" % + (width, height)) + Blob.__init__(self, width, height, + color, emphasis, highlight) + + +# 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 4 5 6 [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 5 6 7 8情 + +# 3 narrow chars (Na) + 40 wide chars (W) +# 情 情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情 + +# 3 narrow chars (Na) + 76 wide chars (W) +# 情 情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情 + +# +#: E501 +# 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 +# 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 +# 3 narrow chars (Na) + 77 wide chars (W) +# 情 情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情情 +# diff --git a/third_party/pep8/tox.ini b/third_party/pep8/tox.ini new file mode 100644 index 00000000000..50a0d007b75 --- /dev/null +++ b/third_party/pep8/tox.ini @@ -0,0 +1,15 @@ +# Tox (http://codespeak.net/~hpk/tox/) 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 + +[testenv] +commands = + {envpython} setup.py install + {envpython} pep8.py --testsuite testsuite + {envpython} pep8.py --statistics pep8.py + {envpython} pep8.py --doctest + {envpython} -m testsuite.test_all |