Merge "Move hacking to pep8 1.5.6"

This commit is contained in:
Jenkins 2014-04-22 12:21:43 +00:00 committed by Gerrit Code Review
commit 85a6386e70
3 changed files with 87 additions and 74 deletions

View File

@ -10,7 +10,7 @@ General
- Use only UNIX style newlines (``\n``), not Windows style (``\r\n``)
- Wrap long lines in parentheses and not a backslash for line continuation.
- Do not write ``except:``, use ``except Exception:`` at the very least
- Include your name with TODOs as in ``#TODO(yourname)``
- Include your name with TODOs as in ``# TODO(yourname)``
- Do not shadow a built-in or reserved word. Example::
def list():

View File

@ -111,13 +111,12 @@ def hacking_todo_format(physical_line, tokens):
"""Check for 'TODO()'.
OpenStack HACKING guide recommendation for TODO:
Include your name with TODOs as in "#TODO(termie)"
Include your name with TODOs as in "# TODO(termie)"
Okay: #TODO(sdague)
Okay: # TODO(sdague)
H101: #TODO fail
H101: #TODO
H101: #TODO (jogo) fail
H101: # TODO fail
H101: # TODO
H101: # TODO (jogo) fail
Okay: TODO = 5
"""
# TODO(jogo): make the following doctests pass:
@ -125,11 +124,12 @@ def hacking_todo_format(physical_line, tokens):
# H101: #TODO(jogo
# TODO(jogo): make this check docstrings as well (don't have to be at top
# of function)
pos = physical_line.find('TODO')
pos1 = physical_line.find('TODO(')
pos2 = physical_line.find('#') # make sure it's a comment
if (pos != pos1 and pos2 >= 0 and pos2 < pos and len(tokens) == 0):
return pos, "H101: Use TODO(NAME)"
for token_type, text, start_index, _, _ in tokens:
if token_type == tokenize.COMMENT:
pos = text.find('TODO')
pos1 = text.find('TODO(')
if (pos != pos1):
return pos + start_index[1], "H101: Use TODO(NAME)"
def _check_for_exact_apache(start, lines):
@ -329,8 +329,8 @@ def hacking_python3x_octal_literals(logical_line, tokens):
H232: f(0755)
"""
for tokentype, text, _, _, _ in tokens:
if tokentype == tokenize.NUMBER:
for token_type, text, _, _, _ in tokens:
if token_type == tokenize.NUMBER:
match = re.match(r"0+([1-9]\d*)", text)
if match:
yield 0, ("H232: Python 3.x incompatible octal %s should be "
@ -761,27 +761,30 @@ def _find_first_of(line, substrings):
return -1, None
def is_docstring(physical_line, previous_logical):
"""Return True if found docstring
def is_docstring(tokens, previous_logical):
"""Return found docstring
'A docstring is a string literal that occurs as the first statement in a
module, function, class,'
http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring
"""
line = physical_line.lstrip()
for token_type, text, start, _, _ in tokens:
if token_type == tokenize.STRING:
break
elif token_type != tokenize.INDENT:
return False
else:
return False
line = text.lstrip()
start, start_triple = _find_first_of(line, START_DOCSTRING_TRIPLE)
end = max([line[-4:-1] == i for i in END_DOCSTRING_TRIPLE])
if (previous_logical.startswith("def ") or
previous_logical.startswith("class ")):
if start == 0:
return True
else:
# Handle multi line comments
return end and start in (-1, len(line) - len(start_triple) - 1)
return text
@flake8ext
def hacking_docstring_start_space(physical_line, previous_logical):
def hacking_docstring_start_space(physical_line, previous_logical, tokens):
r"""Check for docstring not starting with space.
OpenStack HACKING guide recommendation for docstring:
@ -794,23 +797,18 @@ def hacking_docstring_start_space(physical_line, previous_logical):
H401: def foo():\n ''' This is not.'''
H401: def foo():\n r''' This is not.'''
"""
# short circuit so that we don't fail on our own fail test
# when running under external pep8
if physical_line.find("H401: def foo()") != -1:
return
# it's important that we determine this is actually a docstring,
# and not a doc block used somewhere after the first line of a
# function def
if is_docstring(physical_line, previous_logical):
pos = max([physical_line.find(i) for i in START_DOCSTRING_TRIPLE])
if physical_line[pos + 3] == ' ':
return (pos, "H401: docstring should not start with"
docstring = is_docstring(tokens, previous_logical)
if docstring:
start, start_triple = _find_first_of(docstring, START_DOCSTRING_TRIPLE)
if docstring[len(start_triple)] == ' ':
# docstrings get tokenized on the last line of the docstring, so
# we don't know the exact position.
return (0, "H401: docstring should not start with"
" a space")
@flake8ext
def hacking_docstring_one_line(physical_line, previous_logical):
def hacking_docstring_one_line(physical_line, previous_logical, tokens):
r"""Check one line docstring end.
OpenStack HACKING guide recommendation for one line docstring:
@ -832,15 +830,15 @@ def hacking_docstring_one_line(physical_line, previous_logical):
H402: class Foo:\n '''Bad punctuation,'''
H402: class Foo:\n r'''Bad punctuation,'''
"""
# TODO(jogo) make this apply to multi line docstrings as well
docstring = is_docstring(tokens, previous_logical)
if docstring:
if '\n' in docstring:
# multi line docstring
return
line = physical_line.lstrip()
if is_docstring(physical_line, previous_logical):
pos = max([line.find(i) for i in START_DOCSTRING_TRIPLE]) # start
end = max([line[-4:-1] == i for i in END_DOCSTRING_TRIPLE]) # end
if pos != -1 and end and len(line) > pos + 4:
if line[-5] not in ['.', '?', '!']:
return pos, "H402: one line docstring needs punctuation."
return end, "H402: one line docstring needs punctuation."
@flake8ext
@ -854,17 +852,22 @@ def hacking_docstring_multiline_end(physical_line, previous_logical, tokens):
Okay: def foo():\n '''foobar\n\nfoo\nbar\n'''
Okay: class Foo:\n '''foobar\n\nfoo\nbar\n'''
Okay: def foo():\n a = '''not\na\ndocstring'''
Okay: def foo():\n a = '''not\na\ndocstring''' # blah
Okay: def foo():\n pass\n'''foobar\nfoo\nbar\n d'''
H403: def foo():\n '''foobar\nfoo\nbar\ndocstring'''
H403: def foo():\n '''foobar\nfoo\nbar\npretend raw: r'''
H403: class Foo:\n '''foobar\nfoo\nbar\ndocstring'''\n\n
"""
# if find OP tokens, not a docstring
ops = [t for t, _, _, _, _ in tokens if t == tokenize.OP]
if (is_docstring(physical_line, previous_logical) and len(tokens) > 0 and
len(ops) == 0):
pos = max(physical_line.find(i) for i in END_DOCSTRING_TRIPLE)
if physical_line.strip() not in START_DOCSTRING_TRIPLE:
docstring = is_docstring(tokens, previous_logical)
if docstring:
if '\n' not in docstring:
# not a multi line
return
else:
last_line = docstring.split('\n')[-1]
pos = max(last_line.rfind(i) for i in END_DOCSTRING_TRIPLE)
if len(last_line[:pos].strip()) > 0:
# Something before the end docstring triple
return (pos,
"H403: multi line docstrings should end on a new line")
@ -881,19 +884,23 @@ def hacking_docstring_multiline_start(physical_line, previous_logical, tokens):
H404: def foo():\n '''\nfoo\nbar\n'''\n\n
H404: def foo():\n r'''\nfoo\nbar\n'''\n\n
"""
if is_docstring(physical_line, previous_logical):
pos = max([physical_line.find(i) for i in START_DOCSTRING_TRIPLE])
# start of docstring when len(tokens)==0
if len(tokens) == 0 and pos != -1 and len(physical_line) == pos + 4:
if physical_line.strip() in START_DOCSTRING_TRIPLE:
return (pos, "H404: multi line docstring "
docstring = is_docstring(tokens, previous_logical)
if docstring:
if '\n' not in docstring:
# single line docstring
return
start, start_triple = _find_first_of(docstring, START_DOCSTRING_TRIPLE)
lines = docstring.split('\n')
if lines[0].strip() == start_triple:
# docstrings get tokenized on the last line of the docstring, so
# we don't know the exact position.
return (0, "H404: multi line docstring "
"should start without a leading new line")
@flake8ext
def hacking_docstring_summary(physical_line, previous_logical, tokens, lines,
line_number):
r"""Check multi line docstring summary is separted with empty line.
def hacking_docstring_summary(physical_line, previous_logical, tokens):
r"""Check multi line docstring summary is separated with empty line.
OpenStack HACKING guide recommendation for docstring:
Docstring should start with a one-line summary, less than 80 characters.
@ -904,14 +911,16 @@ def hacking_docstring_summary(physical_line, previous_logical, tokens, lines,
H405: def foo():\n r'''foobar\nfoo\nbar\n'''
H405: def foo():\n '''foobar\n'''
"""
if is_docstring(physical_line, previous_logical):
if (len(tokens) == 0 and
not physical_line.strip().endswith(
tuple(END_DOCSTRING_TRIPLE))):
# start of multiline docstring
if lines[line_number].strip():
# second line is not empty
return (len(physical_line) - 1, "H405: multi line docstring "
docstring = is_docstring(tokens, previous_logical)
if docstring:
if '\n' not in docstring:
# not a multi line docstring
return
lines = docstring.split('\n')
if len(lines) > 1 and len(lines[1].strip()) is not 0:
# docstrings get tokenized on the last line of the docstring, so
# we don't know the exact position.
return (0, "H405: multi line docstring "
"summary not separated with an empty line")
@ -1085,15 +1094,19 @@ def hacking_no_cr(physical_line):
@flake8ext
def hacking_no_backsplash_line_continuation(physical_line):
def hacking_no_backsplash_line_continuation(logical_line, tokens):
r"""Wrap lines in parentheses and not a backslash for line continuation.
Okay: a = (5 +\n 6)
H904: b = 5 + \\\n 6
"""
if len(physical_line) > 2 and physical_line[-2] == '\\':
return (len(physical_line) - 2,
"H904: Wrap long lines in parentheses instead of a backslash")
found = False
for token_type, text, start_index, stop_index, line in tokens:
if line.rstrip('\r\n').endswith('\\') and not found:
found = True
yield ((start_index[0], start_index[1]+len(line.strip())-1),
"H904: Wrap long lines in parentheses instead of a "
"backslash")
class GlobalCheck(object):

View File

@ -1,6 +1,6 @@
pbr>=0.6,!=0.7,<1.0
pep8==1.4.6
pep8==1.5.6
pyflakes==0.8.1
flake8==2.1.0