Skip to content

Commit 52ba8c5

Browse files
committed
Add E265 for space before block comment; issue #190
1 parent 00aff36 commit 52ba8c5

6 files changed

Lines changed: 43 additions & 18 deletions

File tree

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Changelog
2222

2323
* Fix false positive E261/E262 when the file contains a BOM. (Issue #193)
2424

25+
* Add E265 for space before block comment. (Issue #190)
26+
2527

2628
1.4.5 (2013-03-06)
2729
------------------

docs/intro.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ This is the current list of error and warning codes:
252252
+----------+----------------------------------------------------------------------+
253253
| E262 | inline comment should start with '# ' |
254254
+----------+----------------------------------------------------------------------+
255+
| E265 | block comment should start with '# ' |
256+
+----------+----------------------------------------------------------------------+
255257
+----------+----------------------------------------------------------------------+
256258
| E271 | multiple spaces after keyword |
257259
+----------+----------------------------------------------------------------------+

pep8.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -764,31 +764,41 @@ def whitespace_around_named_parameter_equals(logical_line, tokens):
764764
prev_end = end
765765

766766

767-
def whitespace_before_inline_comment(logical_line, tokens):
767+
def whitespace_before_comment(logical_line, tokens):
768768
"""
769769
Separate inline comments by at least two spaces.
770770
771771
An inline comment is a comment on the same line as a statement. Inline
772772
comments should be separated by at least two spaces from the statement.
773773
They should start with a # and a single space.
774774
775+
Each line of a block comment starts with a # and a single space
776+
(unless it is indented text inside the comment).
777+
775778
Okay: x = x + 1 # Increment x
776779
Okay: x = x + 1 # Increment x
780+
Okay: # Block comment
777781
E261: x = x + 1 # Increment x
778782
E262: x = x + 1 #Increment x
779783
E262: x = x + 1 # Increment x
784+
E265: #Block comment
780785
"""
781786
prev_end = (0, 0)
782787
for token_type, text, start, end, line in tokens:
783788
if token_type == tokenize.COMMENT:
784-
if not line[:start[1]].strip():
785-
continue
786-
if prev_end[0] == start[0] and start[1] < prev_end[1] + 2:
787-
yield (prev_end,
788-
"E261 at least two spaces before inline comment")
789+
inline_comment = line[:start[1]].strip()
790+
if inline_comment:
791+
if prev_end[0] == start[0] and start[1] < prev_end[1] + 2:
792+
yield (prev_end,
793+
"E261 at least two spaces before inline comment")
789794
symbol, sp, comment = text.partition(' ')
790-
if symbol not in ('#', '#:') or comment[:1].isspace():
791-
yield start, "E262 inline comment should start with '# '"
795+
bad_prefix = symbol not in ('#', '#:')
796+
if inline_comment:
797+
if bad_prefix or comment[:1].isspace():
798+
yield start, "E262 inline comment should start with '# '"
799+
elif bad_prefix:
800+
if text.rstrip('#') and (start[0] > 1 or symbol[1] != '!'):
801+
yield start, "E265 block comment should start with '# '"
792802
elif token_type != tokenize.NL:
793803
prev_end = end
794804

@@ -1307,9 +1317,9 @@ def check_logical(self):
13071317
"""
13081318
self.build_tokens_line()
13091319
self.report.increment_logical_line()
1310-
first_line = self.lines[self.mapping[0][1][2][0] - 1]
1311-
indent = first_line[:self.mapping[0][1][2][1]]
1312-
self.previous_indent_level = self.indent_level
1320+
token0 = self.mapping[0][1] if self.mapping else self.tokens[0]
1321+
first_line = self.lines[token0[2][0] - 1]
1322+
indent = first_line[:token0[2][1]]
13131323
self.indent_level = expand_indent(indent)
13141324
if self.verbose >= 2:
13151325
print(self.logical_line[:80].rstrip())
@@ -1321,12 +1331,17 @@ def check_logical(self):
13211331
if isinstance(offset, tuple):
13221332
orig_number, orig_offset = offset
13231333
else:
1334+
orig_number = token0[2][0]
1335+
orig_offset = token0[2][1] + offset
13241336
for token_offset, token in self.mapping:
13251337
if offset >= token_offset:
13261338
orig_number = token[2][0]
13271339
orig_offset = (token[2][1] + offset - token_offset)
13281340
self.report_error(orig_number, orig_offset, text, check)
1329-
self.previous_logical = self.logical_line
1341+
if self.logical_line:
1342+
self.previous_indent_level = self.indent_level
1343+
self.previous_logical = self.logical_line
1344+
self.tokens = []
13301345

13311346
def check_ast(self):
13321347
try:
@@ -1359,6 +1374,7 @@ def check_all(self, expected=None, line_offset=0):
13591374
self.line_number = 0
13601375
self.indent_char = None
13611376
self.indent_level = 0
1377+
self.previous_indent_level = 0
13621378
self.previous_logical = ''
13631379
self.tokens = []
13641380
self.blank_lines = blank_lines_before_comment = 0
@@ -1383,20 +1399,21 @@ def check_all(self, expected=None, line_offset=0):
13831399
if self.blank_lines < blank_lines_before_comment:
13841400
self.blank_lines = blank_lines_before_comment
13851401
self.check_logical()
1386-
self.tokens = []
13871402
self.blank_lines = blank_lines_before_comment = 0
13881403
elif token_type == tokenize.NL:
13891404
if len(self.tokens) == 1:
13901405
# The physical line contains only this token.
13911406
self.blank_lines += 1
1392-
self.tokens = []
1407+
del self.tokens[0]
1408+
else:
1409+
self.check_logical()
13931410
elif token_type == tokenize.COMMENT and len(self.tokens) == 1:
13941411
if blank_lines_before_comment < self.blank_lines:
13951412
blank_lines_before_comment = self.blank_lines
13961413
self.blank_lines = 0
13971414
if COMMENT_WITH_NL:
13981415
# The comment also ends a physical line
1399-
self.tokens = []
1416+
self.check_logical()
14001417
return self.report.get_file_results()
14011418

14021419

testsuite/E11.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@
1010
#: E113
1111
print
1212
print
13+
#: E111 E113
14+
mimetype = 'application/x-directory'
15+
# 'httpd/unix-directory'
16+
create_date = False

testsuite/test_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,15 @@ def test_styleguide(self):
124124
report = pep8.StyleGuide().check_files([E11])
125125
stdout = sys.stdout.getvalue().splitlines()
126126
self.assertEqual(len(stdout), report.total_errors)
127-
self.assertEqual(report.total_errors, 4)
127+
self.assertEqual(report.total_errors, 6)
128128
self.assertFalse(sys.stderr)
129129
self.reset()
130130

131131
# Passing the paths in the constructor gives same result
132132
report = pep8.StyleGuide(paths=[E11]).check_files()
133133
stdout = sys.stdout.getvalue().splitlines()
134134
self.assertEqual(len(stdout), report.total_errors)
135-
self.assertEqual(report.total_errors, 4)
135+
self.assertEqual(report.total_errors, 6)
136136
self.assertFalse(sys.stderr)
137137
self.reset()
138138

testsuite/test_shell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def test_check_simple(self):
7575
stdout = stdout.splitlines()
7676
self.assertEqual(errcode, 1)
7777
self.assertFalse(stderr)
78-
self.assertEqual(len(stdout), 4)
78+
self.assertEqual(len(stdout), 6)
7979
for line, num, col in zip(stdout, (3, 6, 9, 12), (3, 6, 1, 5)):
8080
path, x, y, msg = line.split(':')
8181
self.assertTrue(path.endswith(E11))

0 commit comments

Comments
 (0)