@@ -782,31 +782,41 @@ def whitespace_around_named_parameter_equals(logical_line, tokens):
782782 prev_end = end
783783
784784
785- def whitespace_before_inline_comment (logical_line , tokens ):
785+ def whitespace_before_comment (logical_line , tokens ):
786786 """
787787 Separate inline comments by at least two spaces.
788788
789789 An inline comment is a comment on the same line as a statement. Inline
790790 comments should be separated by at least two spaces from the statement.
791791 They should start with a # and a single space.
792792
793+ Each line of a block comment starts with a # and a single space
794+ (unless it is indented text inside the comment).
795+
793796 Okay: x = x + 1 # Increment x
794797 Okay: x = x + 1 # Increment x
798+ Okay: # Block comment
795799 E261: x = x + 1 # Increment x
796800 E262: x = x + 1 #Increment x
797801 E262: x = x + 1 # Increment x
802+ E265: #Block comment
798803 """
799804 prev_end = (0 , 0 )
800805 for token_type , text , start , end , line in tokens :
801806 if token_type == tokenize .COMMENT :
802- if not line [:start [1 ]].strip ():
803- continue
804- if prev_end [0 ] == start [0 ] and start [1 ] < prev_end [1 ] + 2 :
805- yield (prev_end ,
806- "E261 at least two spaces before inline comment" )
807+ inline_comment = line [:start [1 ]].strip ()
808+ if inline_comment :
809+ if prev_end [0 ] == start [0 ] and start [1 ] < prev_end [1 ] + 2 :
810+ yield (prev_end ,
811+ "E261 at least two spaces before inline comment" )
807812 symbol , sp , comment = text .partition (' ' )
808- if symbol not in ('#' , '#:' ) or comment [:1 ].isspace ():
809- yield start , "E262 inline comment should start with '# '"
813+ bad_prefix = symbol not in ('#' , '#:' )
814+ if inline_comment :
815+ if bad_prefix or comment [:1 ].isspace ():
816+ yield start , "E262 inline comment should start with '# '"
817+ elif bad_prefix :
818+ if text .rstrip ('#' ) and (start [0 ] > 1 or symbol [1 ] != '!' ):
819+ yield start , "E265 block comment should start with '# '"
810820 elif token_type != tokenize .NL :
811821 prev_end = end
812822
@@ -1371,9 +1381,9 @@ def check_logical(self):
13711381 """
13721382 self .build_tokens_line ()
13731383 self .report .increment_logical_line ()
1374- first_line = self .lines [ self . mapping [0 ][1 ][ 2 ][ 0 ] - 1 ]
1375- indent = first_line [: self .mapping [ 0 ][ 1 ][ 2 ][1 ] ]
1376- self . previous_indent_level = self . indent_level
1384+ token0 = self .mapping [0 ][1 ] if self . mapping else self . tokens [ 0 ]
1385+ first_line = self .lines [ token0 [ 2 ][0 ] - 1 ]
1386+ indent = first_line [: token0 [ 2 ][ 1 ]]
13771387 self .indent_level = expand_indent (indent )
13781388 if self .verbose >= 2 :
13791389 print (self .logical_line [:80 ].rstrip ())
@@ -1385,12 +1395,17 @@ def check_logical(self):
13851395 if isinstance (offset , tuple ):
13861396 (orig_number , orig_offset ) = offset
13871397 else :
1398+ orig_number = token0 [2 ][0 ]
1399+ orig_offset = token0 [2 ][1 ] + offset
13881400 for token_offset , token in self .mapping :
13891401 if offset >= token_offset :
13901402 orig_number = token [2 ][0 ]
13911403 orig_offset = (token [2 ][1 ] + offset - token_offset )
13921404 self .report_error (orig_number , orig_offset , text , check )
1393- self .previous_logical = self .logical_line
1405+ if self .logical_line :
1406+ self .previous_indent_level = self .indent_level
1407+ self .previous_logical = self .logical_line
1408+ self .tokens = []
13941409
13951410 def check_ast (self ):
13961411 try :
@@ -1423,6 +1438,7 @@ def check_all(self, expected=None, line_offset=0):
14231438 self .line_number = 0
14241439 self .indent_char = None
14251440 self .indent_level = 0
1441+ self .previous_indent_level = 0
14261442 self .previous_logical = ''
14271443 self .tokens = []
14281444 self .blank_lines = blank_lines_before_comment = 0
@@ -1447,20 +1463,23 @@ def check_all(self, expected=None, line_offset=0):
14471463 if self .blank_lines < blank_lines_before_comment :
14481464 self .blank_lines = blank_lines_before_comment
14491465 self .check_logical ()
1450- self .tokens = []
14511466 self .blank_lines = blank_lines_before_comment = 0
14521467 elif token_type == tokenize .NL :
14531468 if len (self .tokens ) == 1 :
14541469 # The physical line contains only this token.
14551470 self .blank_lines += 1
1456- self .tokens = []
1471+ del self .tokens [0 ]
1472+ else :
1473+ self .check_logical ()
14571474 elif token_type == tokenize .COMMENT and len (self .tokens ) == 1 :
14581475 if blank_lines_before_comment < self .blank_lines :
14591476 blank_lines_before_comment = self .blank_lines
14601477 self .blank_lines = 0
14611478 if COMMENT_WITH_NL :
14621479 # The comment also ends a physical line
1463- self .tokens = []
1480+ text = text .rstrip ('\r \n ' )
1481+ self .tokens = [(token_type , text ) + token [2 :]]
1482+ self .check_logical ()
14641483 return self .report .get_file_results ()
14651484
14661485
0 commit comments