Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add check for over-indented blocks #705

Merged
merged 1 commit into from
Jan 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ UNRELEASED / 3.0.0
Changes:

* Remove support for EOL Python 2.6 and 3.3. PR #720.
* Add E117 error for over-indented code blocks.

2.4.0 (2018-04-10)
------------------
Expand Down
1 change: 1 addition & 0 deletions docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ This is the current list of error and warning codes:
+------------+----------------------------------------------------------------------+
| E116 | unexpected indentation (comment) |
+------------+----------------------------------------------------------------------+
| E117 | over-indented |
+------------+----------------------------------------------------------------------+
| E121 (\*^) | continuation line under-indented for hanging indent |
+------------+----------------------------------------------------------------------+
Expand Down
6 changes: 5 additions & 1 deletion pycodestyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def tabs_or_spaces(physical_line, indent_char):
tabs and spaces. When using -tt these warnings become errors.
These options are highly recommended!

Okay: if a == 0:\n a = 1\n b = 1
Okay: if a == 0:\n a = 1\n b = 1
E101: if a == 0:\n a = 1\n\tb = 1
"""
indent = INDENT_REGEX.match(physical_line).group(1)
Expand Down Expand Up @@ -534,6 +534,10 @@ def indentation(logical_line, previous_logical, indent_char,
elif not indent_expect and indent_level > previous_indent_level:
yield 0, tmpl % (3 + c, "unexpected indentation")

expected_indent_level = previous_indent_level + 4
if indent_expect and indent_level > expected_indent_level:
yield 0, tmpl % (7, 'over-indented')


@register_check
def continued_indentation(logical_line, tokens, indent_level, hang_closing,
Expand Down
4 changes: 2 additions & 2 deletions testsuite/E10.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
for b in 'xyz':
print a # indented with 8 spaces
print b # indented with 1 tab
#: E101 E122 W191 W191
#: E101 E117 E122 W191 W191
if True:
pass

Expand All @@ -27,7 +27,7 @@ def tearDown(self):
pass

#
#: E101 W191 W191
#: E101 E117 W191 W191
if True:
foo(1,
2)
Expand Down
5 changes: 4 additions & 1 deletion testsuite/E11.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#: E111
if x > 2:
print x
#: E111
#: E111 E117
if True:
print
#: E112
Expand Down Expand Up @@ -34,3 +34,6 @@ def start(self):
# finally:
# sys.exit()
self.master.start()
#: E117
def start():
print
2 changes: 1 addition & 1 deletion testsuite/E90.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
}
#: E901
= [x
#: E901 E101 W191
#: E901 E101 E117 W191
while True:
try:
pass
Expand Down
38 changes: 19 additions & 19 deletions testsuite/W19.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#: W191
#: E117 W191
if False:
print # indented with 1 tab
#:
Expand All @@ -7,56 +7,56 @@
#: W191
y = x == 2 \
or x == 3
#: E101 W191 W504
#: E101 E117 W191 W504
if (
x == (
3
) or
y == 4):
pass
#: E101 W191
#: E101 E117 W191
if x == 2 \
or y > 1 \
or x == 3:
pass
#: E101 W191
#: E101 E117 W191
if x == 2 \
or y > 1 \
or x == 3:
pass
#:

#: E101 W191 W504
#: E101 E117 W191 W504
if (foo == bar and
baz == frop):
pass
#: E101 W191 W504
#: E101 E117 W191 W504
if (
foo == bar and
baz == frop
):
pass
#:

#: E101 E101 W191 W191
#: E101 E101 E117 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
#: E101 E117 W191


def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
#: E101 W191 W504
#: E101 E117 W191 W504
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
#: E101 E101 E101 E101 E117 W191 W191 W191 W191 W191 W191
if bar:
return(
start, 'E121 lines starting with a '
Expand All @@ -65,35 +65,35 @@ def long_function_name(
"bracket's line"
)
#
#: E101 W191 W504
#: E101 E117 W191 W504
# you want vertical alignment, so use a parens
if ((foo.bar("baz") and
foo.bar("frop")
)):
print "yes"
#: E101 W191 W504
#: E101 E117 W191 W504
# also ok, but starting to look like LISP
if ((foo.bar("baz") and
foo.bar("frop"))):
print "yes"
#: E101 W191 W504
#: E101 E117 W191 W504
if (a == 2 or
b == "abc def ghi"
"jkl mno"):
return True
#: E101 W191 W504
#: E101 E117 W191 W504
if (a == 2 or
b == """abc def ghi
jkl mno"""):
return True
#: W191:2:1 W191:3:1 E101:3:2
#: W191:2:1 W191:3:1 E101:3:2 E117
if length > options.max_line_length:
return options.max_line_length, \
"E501 line too long (%d characters)" % length


#
#: E101 W191 W191 W504
#: E101 E117 W191 W191 W504
if os.path.exists(os.path.join(path, PEP8_BIN)):
cmd = ([os.path.join(path, PEP8_BIN)] +
self._pep8_options(targetfile))
Expand All @@ -119,19 +119,19 @@ def long_function_name(
even though the noqa comment is not immediately after the string
''' + foo # noqa
#
#: E101 W191
#: E101 E117 W191
if foo is None and bar is "frop" and \
blah == 'yeah':
blah = 'yeahnah'


#
#: W191 W191 W191
#: E117 W191 W191 W191
if True:
foo(
1,
2)
#: W191 W191 W191 W191 W191
#: E117 W191 W191 W191 W191 W191
def test_keys(self):
"""areas.json - All regions are accounted for."""
expected = set([
Expand Down
4 changes: 2 additions & 2 deletions testsuite/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@ def test_styleguide(self):
report = pycodestyle.StyleGuide().check_files([E11])
stdout = sys.stdout.getvalue().splitlines()
self.assertEqual(len(stdout), report.total_errors)
self.assertEqual(report.total_errors, 17)
self.assertEqual(report.total_errors, 20)
self.assertFalse(sys.stderr)
self.reset()

# Passing the paths in the constructor gives same result
report = pycodestyle.StyleGuide(paths=[E11]).check_files()
stdout = sys.stdout.getvalue().splitlines()
self.assertEqual(len(stdout), report.total_errors)
self.assertEqual(report.total_errors, 17)
self.assertEqual(report.total_errors, 20)
self.assertFalse(sys.stderr)
self.reset()

Expand Down
9 changes: 5 additions & 4 deletions testsuite/test_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ def test_check_simple(self):
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)):
self.assertEqual(len(stdout), 20)
for line, num, col in zip(stdout, (3, 6, 6, 9, 12), (3, 6, 6, 1, 5)):
path, x, y, msg = line.split(':')
self.assertTrue(path.endswith(E11))
self.assertEqual(x, str(num))
Expand Down Expand Up @@ -170,10 +170,11 @@ def test_check_diff(self):
"+ print"]
self.stdin = '\n'.join(diff_lines)
stdout, stderr, errcode = self.pycodestyle('--diff')
(stdout,) = stdout.splitlines()
stdout = stdout.splitlines()
self.assertEqual(errcode, 1)
self.assertFalse(stderr)
self.assertTrue('testsuite/E11.py:6:6: E111 ' in stdout)
self.assertTrue('testsuite/E11.py:6:6: E111 ' in stdout[0])
self.assertTrue('testsuite/E11.py:6:6: E117 ' in stdout[1])

# missing '--diff'
self.stdin = '\n'.join(diff_lines)
Expand Down