Skip to content

Commit

Permalink
Fix issue #400: Require two blank lines after toplevel def, class
Browse files Browse the repository at this point in the history
  • Loading branch information
benesch authored and IanLee1521 committed Jun 25, 2016
1 parent dc08dad commit 6b75c4d
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Changes:
* Added check E275 for whitespace on `from ... import ...` lines; #489 / #491
* Added W503 to the list of codes ignored by default ignore list; #498
* Removed use of project level `.pep8` configuration file; #364
* Added check E305 for two blank lines after toplevel method and toplevel class; #400

Bugs:

Expand Down
2 changes: 2 additions & 0 deletions docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ This is the current list of error and warning codes:
+------------+----------------------------------------------------------------------+
| E304 | blank lines found after function decorator |
+------------+----------------------------------------------------------------------+
| E305 | expected 2 blank lines after end of function or class |
+------------+----------------------------------------------------------------------+
+------------+----------------------------------------------------------------------+
| **E4** | *Import* |
+------------+----------------------------------------------------------------------+
Expand Down
13 changes: 12 additions & 1 deletion pycodestyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ def maximum_line_length(physical_line, max_line_length, multiline, noqa):


def blank_lines(logical_line, blank_lines, indent_level, line_number,
blank_before, previous_logical, previous_indent_level):
blank_before, previous_logical, previous_logical_toplevel,
previous_indent_level):
r"""Separate top-level function and class definitions with two blank lines.
Method definitions inside a class are separated by a single blank line.
Expand All @@ -256,6 +257,7 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number,
E303: def a():\n pass\n\n\n\ndef b(n):\n pass
E303: def a():\n\n\n\n pass
E304: @decorator\n\ndef a():\n pass
E305: def a():\n pass\na()
"""
if line_number < 3 and not previous_logical:
return # Don't expect blank lines before the first line
Expand All @@ -271,6 +273,10 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number,
yield 0, "E301 expected 1 blank line, found 0"
elif blank_before != 2:
yield 0, "E302 expected 2 blank lines, found %d" % blank_before
elif (logical_line and not indent_level and blank_before != 2 and
previous_logical_toplevel.startswith(('def', 'class'))):
yield 0, "E305 expected 2 blank lines after " \
"class or function definition, found %d" % blank_before


def extraneous_whitespace(logical_line):
Expand Down Expand Up @@ -1450,6 +1456,8 @@ def init_checks_registry():
mod = inspect.getmodule(register_check)
for (name, function) in inspect.getmembers(mod, inspect.isfunction):
register_check(function)


init_checks_registry()


Expand Down Expand Up @@ -1608,6 +1616,8 @@ def check_logical(self):
if self.logical_line:
self.previous_indent_level = self.indent_level
self.previous_logical = self.logical_line
if not self.indent_level:
self.previous_logical_toplevel = self.logical_line
self.blank_lines = 0
self.tokens = []

Expand Down Expand Up @@ -1678,6 +1688,7 @@ def check_all(self, expected=None, line_offset=0):
self.indent_char = None
self.indent_level = self.previous_indent_level = 0
self.previous_logical = ''
self.previous_logical_toplevel = ''
self.tokens = []
self.blank_lines = self.blank_before = 0
parens = 0
Expand Down
3 changes: 3 additions & 0 deletions testsuite/E12not.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def long_function_name(
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))
Expand Down Expand Up @@ -400,6 +401,7 @@ def unicode2html(s):
.replace('"', '&#34;')
.replace('\n', '<br>\n'))


#
parser.add_option('--count', action='store_true',
help="print total number of errors and warnings "
Expand Down Expand Up @@ -616,6 +618,7 @@ def other_example():
for key, val in node.items()
))]


foo([
'bug'
])
Expand Down
1 change: 1 addition & 0 deletions testsuite/E22.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ def halves(n):
def squares(n):
return (i**2 for i in range(n))


ENG_PREFIXES = {
-6: "\u03bc", # Greek letter mu
-3: "m",
Expand Down
29 changes: 29 additions & 0 deletions testsuite/E30.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,32 @@ def function():
It gives error E303: too many blank lines (3)
"""
#:

#: E305:7:1
def a():
print

# comment

# another comment
a()
#: E305:8:1
def a():
print

# comment

# another comment

try:
a()
except:
pass
#: E305:5:1
def a():
print

# Two spaces before comments, too.
if a():
a()
#:
1 change: 1 addition & 0 deletions testsuite/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,5 +196,6 @@ def run_tests(style):
init_tests(style)
return style.check_files()


# nose should not collect these functions
init_tests.__test__ = run_tests.__test__ = False
1 change: 1 addition & 0 deletions testsuite/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ def suite():
def _main():
return unittest.TextTestRunner(verbosity=2).run(suite())


if __name__ == '__main__':
sys.exit(not _main())

0 comments on commit 6b75c4d

Please sign in to comment.