summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorent Xicluna <florent.xicluna@gmail.com>2014-03-28 22:20:57 +0100
committerFlorent Xicluna <florent.xicluna@gmail.com>2014-03-28 22:20:57 +0100
commitf9bde22e49df43c4f5c7d9d1cd03573b0c855bad (patch)
treefb3ab064dc9be35bb5501468f0ea90a9d9f5eb24
parent6a3dfa8ae7934053665ef61e36d79a8e5a8ef922 (diff)
downloadpep8-f9bde22e49df43c4f5c7d9d1cd03573b0c855bad.tar.gz
Back to development; review some docstrings in relation with PEP 257.
-rw-r--r--CHANGES.txt6
-rw-r--r--LICENSE2
-rwxr-xr-xpep8.py226
3 files changed, 90 insertions, 144 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 444909c..528cf0d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -2,6 +2,12 @@ Changelog
=========
+1.5.x (unreleased)
+------------------
+
+
+
+
1.5.1 (2014-03-27)
------------------
diff --git a/LICENSE b/LICENSE
index 0a5a15d..70242b8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
Copyright © 2006-2009 Johann C. Rocholl <johann@rocholl.net>
-Copyright © 2009-2013 Florent Xicluna <florent.xicluna@gmail.com>
+Copyright © 2009-2014 Florent Xicluna <florent.xicluna@gmail.com>
Licensed under the terms of the Expat License
diff --git a/pep8.py b/pep8.py
index c50dd11..fd99a91 100755
--- a/pep8.py
+++ b/pep8.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# pep8.py - Check Python source code formatting, according to PEP 8
# Copyright (C) 2006-2009 Johann C. Rocholl <johann@rocholl.net>
-# Copyright (C) 2009-2013 Florent Xicluna <florent.xicluna@gmail.com>
+# Copyright (C) 2009-2014 Florent Xicluna <florent.xicluna@gmail.com>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
@@ -24,8 +24,7 @@
# SOFTWARE.
r"""
-Check Python source code formatting, according to PEP 8:
-http://www.python.org/dev/peps/pep-0008/
+Check Python source code formatting, according to PEP 8.
For usage and a list of options, try this:
$ python pep8.py -h
@@ -45,7 +44,7 @@ W warnings
700 statements
900 syntax error
"""
-__version__ = '1.5.1'
+__version__ = '1.5.2a0'
import os
import sys
@@ -118,8 +117,7 @@ COMMENT_WITH_NL = tokenize.generate_tokens(['#\n'].pop).send(None)[1] == '#\n'
def tabs_or_spaces(physical_line, indent_char):
- r"""
- Never mix tabs and spaces.
+ r"""Never mix tabs and spaces.
The most popular way of indenting Python is with spaces only. The
second-most popular way is with tabs only. Code indented with a mixture
@@ -138,9 +136,7 @@ def tabs_or_spaces(physical_line, indent_char):
def tabs_obsolete(physical_line):
- r"""
- For new projects, spaces-only are strongly recommended over tabs. Most
- editors have features that make this easy to do.
+ r"""For new projects, spaces-only are strongly recommended over tabs.
Okay: if True:\n return
W191: if True:\n\treturn
@@ -151,16 +147,7 @@ def tabs_obsolete(physical_line):
def trailing_whitespace(physical_line):
- r"""
- JCR: Trailing whitespace is superfluous.
- FBM: Except when it occurs as part of a blank line (i.e. the line is
- nothing but whitespace). According to Python docs[1] a line with only
- whitespace is considered a blank line, and is to be ignored. However,
- matching a blank line to its indentation level avoids mistakenly
- terminating a multi-line statement (e.g. class declaration) when
- pasting code into the standard Python interpreter.
-
- [1] http://docs.python.org/reference/lexical_analysis.html#blank-lines
+ r"""Trailing whitespace is superfluous.
The warning returned varies on whether the line itself is blank, for easier
filtering for those who want to indent their blank lines.
@@ -181,8 +168,7 @@ def trailing_whitespace(physical_line):
def trailing_blank_lines(physical_line, lines, line_number):
- r"""
- JCR: Trailing blank lines are superfluous.
+ r"""Trailing blank lines are superfluous.
Okay: spam(1)
W391: spam(1)\n
@@ -192,8 +178,7 @@ def trailing_blank_lines(physical_line, lines, line_number):
def missing_newline(physical_line):
- """
- JCR: The last line should have a newline.
+ r"""The last line should have a newline.
Reports warning W292.
"""
@@ -202,8 +187,7 @@ def missing_newline(physical_line):
def maximum_line_length(physical_line, max_line_length, multiline):
- """
- Limit all lines to a maximum of 79 characters.
+ r"""Limit all lines to a maximum of 79 characters.
There are still many devices around that are limited to 80 character
lines; plus, limiting windows to 80 characters makes it possible to have
@@ -242,8 +226,7 @@ def maximum_line_length(physical_line, max_line_length, multiline):
def blank_lines(logical_line, blank_lines, indent_level, line_number,
previous_logical, previous_indent_level):
- r"""
- Separate top-level function and class definitions with two blank lines.
+ r"""Separate top-level function and class definitions with two blank lines.
Method definitions inside a class are separated by a single blank line.
@@ -279,11 +262,10 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number,
def extraneous_whitespace(logical_line):
- """
- Avoid extraneous whitespace in the following situations:
+ r"""Avoid extraneous whitespace.
+ Avoid extraneous whitespace in these situations:
- Immediately inside parentheses, brackets or braces.
-
- Immediately before a comma, semicolon, or colon.
Okay: spam(ham[1], {eggs: 2})
@@ -312,8 +294,7 @@ def extraneous_whitespace(logical_line):
def whitespace_around_keywords(logical_line):
- r"""
- Avoid extraneous whitespace around keywords.
+ r"""Avoid extraneous whitespace around keywords.
Okay: True and False
E271: True and False
@@ -336,8 +317,7 @@ def whitespace_around_keywords(logical_line):
def missing_whitespace(logical_line):
- """
- JCR: Each comma, semicolon or colon should be followed by whitespace.
+ r"""Each comma, semicolon or colon should be followed by whitespace.
Okay: [a, b]
Okay: (3,)
@@ -364,8 +344,7 @@ def missing_whitespace(logical_line):
def indentation(logical_line, previous_logical, indent_char,
indent_level, previous_indent_level):
- r"""
- Use 4 spaces per indentation level.
+ r"""Use 4 spaces per indentation level.
For really old code that you don't want to mess up, you can continue to
use 8-space tabs.
@@ -391,15 +370,14 @@ def indentation(logical_line, previous_logical, indent_char,
def continued_indentation(logical_line, tokens, indent_level, hang_closing,
indent_char, noqa, verbose):
- r"""
- Continuation lines should align wrapped elements either vertically using
- Python's implicit line joining inside parentheses, brackets and braces, or
- using a hanging indent.
+ r"""Continuation lines indentation.
- When using a hanging indent the following considerations should be applied:
+ Continuation lines should align wrapped elements either vertically
+ using Python's implicit line joining inside parentheses, brackets
+ and braces, or using a hanging indent.
+ When using a hanging indent these considerations should be applied:
- there should be no arguments on the first line, and
-
- further indentation should be used to clearly distinguish itself as a
continuation line.
@@ -586,14 +564,12 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing,
def whitespace_before_parameters(logical_line, tokens):
- """
- Avoid extraneous whitespace in the following situations:
+ r"""Avoid extraneous whitespace.
- - Immediately before the open parenthesis that starts the argument
- list of a function call.
-
- - Immediately before the open parenthesis that starts an indexing or
- slicing.
+ Avoid extraneous whitespace in the following situations:
+ - before the open parenthesis that starts the argument list of a
+ function call.
+ - before the open parenthesis that starts an indexing or slicing.
Okay: spam(1)
E211: spam (1)
@@ -620,11 +596,7 @@ def whitespace_before_parameters(logical_line, tokens):
def whitespace_around_operator(logical_line):
- r"""
- Avoid extraneous whitespace in the following situations:
-
- - More than one space around an assignment (or other) operator to
- align it with another.
+ r"""Avoid extraneous whitespace around an operator.
Okay: a = 12 + 3
E221: a = 4 + 5
@@ -647,13 +619,15 @@ def whitespace_around_operator(logical_line):
def missing_whitespace_around_operator(logical_line, tokens):
- r"""
+ r"""Surround operators with a single space on either side.
+
- Always surround these binary operators with a single space on
either side: assignment (=), augmented assignment (+=, -= etc.),
- comparisons (==, <, >, !=, <>, <=, >=, in, not in, is, is not),
+ comparisons (==, <, >, !=, <=, >=, in, not in, is, is not),
Booleans (and, or, not).
- - Use spaces around arithmetic operators.
+ - If operators with different priorities are used, consider adding
+ whitespace around the operators with the lowest priorities.
Okay: i = i + 1
Okay: submitted += 1
@@ -744,11 +718,7 @@ def missing_whitespace_around_operator(logical_line, tokens):
def whitespace_around_comma(logical_line):
- r"""
- Avoid extraneous whitespace in the following situations:
-
- - More than one space around an assignment (or other) operator to
- align it with another.
+ r"""Avoid extraneous whitespace after a comma or a colon.
Note: these checks are disabled by default
@@ -766,7 +736,8 @@ def whitespace_around_comma(logical_line):
def whitespace_around_named_parameter_equals(logical_line, tokens):
- """
+ r"""Don't use spaces around the '=' sign in function arguments.
+
Don't use spaces around the '=' sign when used to indicate a
keyword argument or a default parameter value.
@@ -802,8 +773,7 @@ def whitespace_around_named_parameter_equals(logical_line, tokens):
def whitespace_before_comment(logical_line, tokens):
- """
- Separate inline comments by at least two spaces.
+ r"""Separate inline comments by at least two spaces.
An inline comment is a comment on the same line as a statement. Inline
comments should be separated by at least two spaces from the statement.
@@ -841,8 +811,7 @@ def whitespace_before_comment(logical_line, tokens):
def imports_on_separate_lines(logical_line):
- r"""
- Imports should usually be on separate lines.
+ r"""Imports should usually be on separate lines.
Okay: import os\nimport sys
E401: import sys, os
@@ -861,13 +830,11 @@ def imports_on_separate_lines(logical_line):
def compound_statements(logical_line):
- r"""
- Compound statements (multiple statements on the same line) are
- generally discouraged.
+ r"""Compound statements (on the same line) are generally discouraged.
While sometimes it's okay to put an if/for/while with a small body
- on the same line, never do this for multi-clause statements. Also
- avoid folding such long lines!
+ on the same line, never do this for multi-clause statements.
+ Also avoid folding such long lines!
Okay: if foo == 'blah':\n do_blah_thing()
Okay: do_one()
@@ -907,8 +874,7 @@ def compound_statements(logical_line):
def explicit_line_join(logical_line, tokens):
- r"""
- Avoid explicit line join between brackets.
+ r"""Avoid explicit line join between brackets.
The preferred way of wrapping long lines is by using Python's implied line
continuation inside parentheses, brackets and braces. Long lines can be
@@ -942,7 +908,8 @@ def explicit_line_join(logical_line, tokens):
def comparison_to_singleton(logical_line, noqa):
- """
+ r"""Comparison to singletons should use "is" or "is not".
+
Comparisons to singletons like None should always be done
with "is" or "is not", never the equality operators.
@@ -972,9 +939,7 @@ def comparison_to_singleton(logical_line, noqa):
def comparison_negative(logical_line):
- r"""
- Negative comparison, either identity or membership, should be
- done using "not in" and "is not".
+ r"""Negative comparison should be done using "not in" and "is not".
Okay: if x not in y:\n pass
Okay: assert (X in Y or X is Z)
@@ -995,9 +960,9 @@ def comparison_negative(logical_line):
def comparison_type(logical_line):
- """
- Object type comparisons should always use isinstance() instead of
- comparing types directly.
+ r"""Object type comparisons should always use isinstance().
+
+ Do not compare types directly.
Okay: if isinstance(obj, int):
E721: if type(obj) is type(1):
@@ -1018,9 +983,7 @@ def comparison_type(logical_line):
def python_3000_has_key(logical_line, noqa):
- r"""
- The {}.has_key() method is removed in the Python 3.
- Use the 'in' operation instead.
+ r"""The {}.has_key() method is removed in Python 3: use the 'in' operator.
Okay: if "alph" in d:\n print d["alph"]
W601: assert d.has_key('alph')
@@ -1031,14 +994,9 @@ def python_3000_has_key(logical_line, noqa):
def python_3000_raise_comma(logical_line):
- """
- When raising an exception, use "raise ValueError('message')"
- instead of the older form "raise ValueError, 'message'".
+ r"""When raising an exception, use "raise ValueError('message')".
- The paren-using form is preferred because when the exception arguments
- are long or include string formatting, you don't need to use line
- continuation characters thanks to the containing parentheses. The older
- form is removed in Python 3.
+ The older form is removed in Python 3.
Okay: raise DummyError("Message")
W602: raise DummyError, "Message"
@@ -1049,9 +1007,8 @@ def python_3000_raise_comma(logical_line):
def python_3000_not_equal(logical_line):
- """
- != can also be written <>, but this is an obsolete usage kept for
- backwards compatibility only. New code should always use !=.
+ r"""New code should always use != instead of <>.
+
The older syntax is removed in Python 3.
Okay: if a != 'no':
@@ -1063,9 +1020,7 @@ def python_3000_not_equal(logical_line):
def python_3000_backticks(logical_line):
- """
- Backticks are removed in Python 3.
- Use repr() instead.
+ r"""Backticks are removed in Python 3: use repr() instead.
Okay: val = repr(1 + 2)
W604: val = `1 + 2`
@@ -1083,6 +1038,7 @@ def python_3000_backticks(logical_line):
if '' == ''.encode():
# Python 2: implicit encoding.
def readlines(filename):
+ """Read the source code."""
f = open(filename)
try:
return f.readlines()
@@ -1093,6 +1049,7 @@ if '' == ''.encode():
else:
# Python 3
def readlines(filename):
+ """Read the source code."""
f = open(filename, 'rb')
try:
coding, lines = tokenize.detect_encoding(f.readline)
@@ -1109,13 +1066,12 @@ else:
def stdin_get_value():
return TextIOWrapper(sys.stdin.buffer, errors='ignore').read()
-readlines.__doc__ = " Read the source code."
noqa = re.compile(r'# no(?:qa|pep8)\b', re.I).search
def expand_indent(line):
- r"""
- Return the amount of indentation.
+ r"""Return the amount of indentation.
+
Tabs are expanded to the next multiple of 8.
>>> expand_indent(' ')
@@ -1143,8 +1099,7 @@ def expand_indent(line):
def mute_string(text):
- """
- Replace contents with 'xxx' to prevent syntax matching.
+ """Replace contents with 'xxx' to prevent syntax matching.
>>> mute_string('"abc"')
'"xxx"'
@@ -1204,8 +1159,8 @@ def normalize_paths(value, parent=os.curdir):
def filename_match(filename, patterns, default=True):
- """
- Check if patterns contains a pattern that matches filename.
+ """Check if patterns contains a pattern that matches filename.
+
If patterns is unspecified, this always returns True.
"""
if not patterns:
@@ -1222,9 +1177,7 @@ _checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}}
def register_check(check, codes=None):
- """
- Register a new check object.
- """
+ """Register a new check object."""
def _add_check(check, kind, codes, args):
if check in _checks[kind]:
_checks[kind][check][0].extend(codes or [])
@@ -1242,9 +1195,9 @@ def register_check(check, codes=None):
def init_checks_registry():
- """
- Register all globally visible functions where the first argument name
- is 'physical_line' or 'logical_line'.
+ """Register all globally visible functions.
+
+ The first argument name is either 'physical_line' or 'logical_line'.
"""
mod = inspect.getmodule(register_check)
for (name, function) in inspect.getmembers(mod, inspect.isfunction):
@@ -1253,9 +1206,7 @@ init_checks_registry()
class Checker(object):
- """
- Load a Python source file, tokenize it, check coding style.
- """
+ """Load a Python source file, tokenize it, check coding style."""
def __init__(self, filename=None, lines=None,
options=None, report=None, **kwargs):
@@ -1298,6 +1249,7 @@ class Checker(object):
self.report_error = self.report.error
def report_invalid_syntax(self):
+ """Check if the syntax is valid."""
(exc_type, exc) = sys.exc_info()[:2]
if len(exc.args) > 1:
offset = exc.args[1]
@@ -1308,12 +1260,9 @@ class Checker(object):
self.report_error(offset[0], offset[1] or 0,
'E901 %s: %s' % (exc_type.__name__, exc.args[0]),
self.report_invalid_syntax)
- report_invalid_syntax.__doc__ = " Check if the syntax is valid."
def readline(self):
- """
- Get the next line from the input buffer.
- """
+ """Get the next line from the input buffer."""
self.line_number += 1
if self.line_number > len(self.lines):
return ''
@@ -1323,18 +1272,14 @@ class Checker(object):
return line
def run_check(self, check, argument_names):
- """
- Run a check plugin.
- """
+ """Run a check plugin."""
arguments = []
for name in argument_names:
arguments.append(getattr(self, name))
return check(*arguments)
def check_physical(self, line):
- """
- Run all physical checks on a raw input line.
- """
+ """Run all physical checks on a raw input line."""
self.physical_line = line
for name, check, argument_names in self._physical_checks:
result = self.run_check(check, argument_names)
@@ -1345,9 +1290,7 @@ class Checker(object):
self.indent_char = line[0]
def build_tokens_line(self):
- """
- Build a logical line from tokens.
- """
+ """Build a logical line from tokens."""
self.mapping = []
logical = []
comments = []
@@ -1385,9 +1328,7 @@ class Checker(object):
# assert self.logical_line.strip() == self.logical_line
def check_logical(self):
- """
- Build a line from tokens and run all logical checks on it.
- """
+ """Build a line from tokens and run all logical checks on it."""
self.build_tokens_line()
self.report.increment_logical_line()
token0 = self.mapping[0][1] if self.mapping else self.tokens[0]
@@ -1417,6 +1358,7 @@ class Checker(object):
self.tokens = []
def check_ast(self):
+ """Build the file's AST and run all AST checks."""
try:
tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST)
except (SyntaxError, TypeError):
@@ -1428,6 +1370,7 @@ class Checker(object):
self.report_error(lineno, offset, text, check)
def generate_tokens(self):
+ """Tokenize the file, run physical line checks and yield tokens."""
if self._io_error:
self.report_error(1, 0, 'E902 %s' % self._io_error, readlines)
tokengen = tokenize.generate_tokens(self.readline)
@@ -1439,9 +1382,7 @@ class Checker(object):
self.report_invalid_syntax()
def maybe_check_physical(self, token):
- """
- If appropriate (based on token), check current physical line(s).
- """
+ """If appropriate (based on token), check current physical line(s)."""
# Called after every token, but act only on end of line.
if token[0] in (tokenize.NEWLINE, tokenize.NL):
# Obviously, a newline token ends a single physical line.
@@ -1471,9 +1412,7 @@ class Checker(object):
self.multiline = False
def check_all(self, expected=None, line_offset=0):
- """
- Run all checks on the input file.
- """
+ """Run all checks on the input file."""
self.report.init_file(self.filename, self.lines, expected, line_offset)
if self._ast_checks:
self.check_ast()
@@ -1527,6 +1466,7 @@ class Checker(object):
class BaseReport(object):
"""Collect the results of the checks."""
+
print_filename = False
def __init__(self, options):
@@ -1589,8 +1529,7 @@ class BaseReport(object):
for key in self.messages if key.startswith(prefix)])
def get_statistics(self, prefix=''):
- """
- Get statistics for message codes that start with the prefix.
+ """Get statistics for message codes that start with the prefix.
prefix='' matches all errors and warnings
prefix='E' matches all errors
@@ -1663,7 +1602,7 @@ class StandardReport(BaseReport):
print(line.rstrip())
print(' ' * offset + '^')
if self._show_pep8 and doc:
- print(doc.lstrip('\n').rstrip())
+ print(' ' + doc.strip())
return self.file_errors
@@ -1774,8 +1713,9 @@ class StyleGuide(object):
runner(os.path.join(root, filename))
def excluded(self, filename, parent=None):
- """
- Check if options.exclude contains a pattern that matches filename.
+ """Check if the file should be excluded.
+
+ Check if 'options.exclude' contains a pattern that matches filename.
"""
if not self.options.exclude:
return False
@@ -1788,8 +1728,7 @@ class StyleGuide(object):
return filename_match(filename, self.options.exclude)
def ignore_code(self, code):
- """
- Check if the error code should be ignored.
+ """Check if the error code should be ignored.
If 'options.select' contains a prefix of the error code,
return False. Else, if 'options.ignore' contains a prefix of
@@ -1802,7 +1741,8 @@ class StyleGuide(object):
not code.startswith(self.options.select))
def get_checks(self, argument_name):
- """
+ """Get all the checks for this category.
+
Find all globally visible functions where the first argument name
starts with argument_name and which contain selected tests.
"""