From 65168577cf4cd1376c44bca08fde38db6679d415 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Sat, 8 Jul 2017 13:57:39 +0200 Subject: [PATCH] Fix comment issues (E26x). --- parso/normalizer.py | 3 + parso/python/normalizer.py | 19 ++++- test/normalizer_issue_files/E101.py | 6 +- test/normalizer_issue_files/E11.py | 6 +- test/normalizer_issue_files/E12_not_first.py | 12 +-- test/normalizer_issue_files/E12_not_second.py | 9 +-- test/normalizer_issue_files/E12_third.py | 3 +- test/normalizer_issue_files/E26.py | 78 +++++++++++++++++++ test/normalizer_issue_files/E30.py | 3 +- test/normalizer_issue_files/E50.py | 3 +- test/test_pep8.py | 7 +- 11 files changed, 113 insertions(+), 36 deletions(-) create mode 100644 test/normalizer_issue_files/E26.py diff --git a/parso/normalizer.py b/parso/normalizer.py index 9607749..e7262c3 100644 --- a/parso/normalizer.py +++ b/parso/normalizer.py @@ -64,6 +64,9 @@ class Issue(object): def __hash__(self): return hash((self.code, self.start_pos)) + def __repr__(self): + return '<%s: %s>' % (self.__class__.__name__, self.code) + class Rule(object): diff --git a/parso/python/normalizer.py b/parso/python/normalizer.py index b845a37..f492e58 100644 --- a/parso/python/normalizer.py +++ b/parso/python/normalizer.py @@ -2,7 +2,6 @@ import re from contextlib import contextmanager from parso.normalizer import Normalizer, Rule, NormalizerConfig -from parso.python.prefix import PrefixPart _IMPORT_TYPES = ('import_name', 'import_from') @@ -11,7 +10,6 @@ _SUITE_INTRODUCERS = ('classdef', 'funcdef', 'if_stmt', 'while_stmt', _NON_STAR_TYPES = ('term', 'import_from', 'power') _OPENING_BRACKETS = '(', '[', '{' _CLOSING_BRACKETS = ')', ']', '}' -# TODO ~ << >> & | ^ _FACTOR = '+', '-', '~' _ALLOW_SPACE = '*', '+', '-', '**', '/', '//', '@' _BITWISE_OPERATOR = '<<', '>>', '|', '&', '^' @@ -392,6 +390,18 @@ class PEP8Normalizer(Normalizer): node = self._indentation_tos if type_ == 'comment': + if value.startswith('##'): + # Whole blocks of # should not raise an error. + if value.lstrip('#'): + self.add_issue(266, "Too many leading '#' for block comment.", leaf) + elif self._on_newline: + if not re.match('#:? ', value) and not value == '#' \ + and not (value.startswith('#!') and leaf.start_pos == (1, 0)): + self.add_issue(265, "Block comment should start with '# '", leaf) + else: + if not re.match('#:? [^ ]', value): + self.add_issue(262, "Inline comment should start with '# '", leaf) + self._reset_newlines(spacing, actual_leaf, is_comment=True) elif type_ == 'newline': if self._newline_count > self._get_wanted_blank_lines_count(): @@ -420,7 +430,6 @@ class PEP8Normalizer(Normalizer): spacing, parent=self._indentation_tos ) - elif self._on_newline: indentation = spacing.value if node.type == IndentationTypes.BACKSLASH \ @@ -558,7 +567,8 @@ class PEP8Normalizer(Normalizer): if '\t' in spaces: self.add_issue(223, 'Used tab to separate tokens', spacing) elif type_ == 'comment': - pass # TODO + if len(spaces) < self._config.spaces_before_comment: + self.add_issue(261, 'At least two spaces before inline comment', spacing) elif type_ == 'newline': add_if_spaces(291, 'Trailing whitespace', spacing) elif len(spaces) > 1: @@ -707,6 +717,7 @@ class PEP8NormalizerConfig(NormalizerConfig): self.closing_bracket_hanging_indentation = '' self.break_after_binary = False self.max_characters = 79 + self.spaces_before_comment = 2 @PEP8NormalizerConfig.register_rule diff --git a/test/normalizer_issue_files/E101.py b/test/normalizer_issue_files/E101.py index 53b5c5f..ff3c76d 100644 --- a/test/normalizer_issue_files/E101.py +++ b/test/normalizer_issue_files/E101.py @@ -58,7 +58,7 @@ if bar: "to match that of the opening " "bracket's line" ) -# + # you want vertical alignment, so use a parens #: E101+3 if ((foo.bar("baz") and @@ -83,7 +83,6 @@ if length > options.max_line_length: "E501 line too long (%d characters)" % length -# #: E101+1 E101+2 if os.path.exists(os.path.join(path, PEP8_BIN)): cmd = ([os.path.join(path, PEP8_BIN)] + @@ -109,14 +108,13 @@ or long long long long long long long long long long long long long long long lo will get no warning even though the noqa comment is not immediately after the string ''' + foo # noqa -# + #: E101+2 if foo is None and bar is "frop" and \ blah == 'yeah': blah = 'yeahnah' -# #: E101+1 E101+2 E101+3 if True: foo( diff --git a/test/normalizer_issue_files/E11.py b/test/normalizer_issue_files/E11.py index b9a895f..816a9be 100644 --- a/test/normalizer_issue_files/E11.py +++ b/test/normalizer_issue_files/E11.py @@ -27,8 +27,8 @@ def start(self): # foo #: E111:8 # bar - if True: # Hello - self.master.start() # Comment + if True: # Hello + self.master.start() # Comment # try: #: E111:12 # self.master.start() @@ -57,4 +57,4 @@ def start(self): # Correct comment # except MasterExit: #: E111:0 # self.shutdown() - self.master.start() # comment + self.master.start() # comment diff --git a/test/normalizer_issue_files/E12_not_first.py b/test/normalizer_issue_files/E12_not_first.py index 738f7df..6f6daa7 100644 --- a/test/normalizer_issue_files/E12_not_first.py +++ b/test/normalizer_issue_files/E12_not_first.py @@ -49,9 +49,6 @@ a = (123, ) -# - - if start[1] > end_col and not ( over_indent == 4 and indent_next): return (0, "E121 continuation line over-" @@ -91,7 +88,6 @@ print "hello", ( foo = long_function_name(var_one, var_two, var_three, var_four) -# # Extra indentation is not necessary. foo = long_function_name( var_one, var_two, @@ -173,8 +169,6 @@ foo = my.func({ }, "baz") -# - fooff(aaaa, cca( vvv, @@ -189,7 +183,6 @@ fooff(aaaa, aaa, dadd), "visual indentation is not a multiple of four",) -# if bar: return ( @@ -198,7 +191,7 @@ if bar: "to match that of the opening " "bracket's line" ) -# + # you want vertical alignment, so use a parens if ((foo.bar("baz") and foo.bar("frop") @@ -333,9 +326,6 @@ rv.update( ) -# - - event_obj.write(cursor, user_id, { 'user': user, 'summary': text, diff --git a/test/normalizer_issue_files/E12_not_second.py b/test/normalizer_issue_files/E12_not_second.py index 8949ec6..3169fca 100644 --- a/test/normalizer_issue_files/E12_not_second.py +++ b/test/normalizer_issue_files/E12_not_second.py @@ -52,7 +52,6 @@ def unicode2html(s): .replace('\n', '
\n')) -# parser.add_option('--count', action='store_true', help="print total number of errors and warnings " "to standard error and set exit code to 1 if " @@ -75,9 +74,6 @@ add_option('--count', "total is not null") -# - - help = ("print total number of errors " + "to standard error") @@ -163,7 +159,6 @@ troublesome_hash = { "when you're indented": "stringwithalongtoken you don't want to break", } -# d = dict('foo', help="exclude files or directories which match these " "comma separated patterns (default: %s)" % @@ -207,7 +202,7 @@ d = { # comment if a > b and \ c > d: moo_like_a_cow() -# + my_list = [ 1, 2, 3, 4, 5, 6, @@ -249,7 +244,7 @@ bar( bar( 1).zap( 2) -# + if True: def example_issue254(): diff --git a/test/normalizer_issue_files/E12_third.py b/test/normalizer_issue_files/E12_third.py index 0026936..f0c05aa 100644 --- a/test/normalizer_issue_files/E12_third.py +++ b/test/normalizer_issue_files/E12_third.py @@ -86,8 +86,7 @@ if True: ), dict(name=token.undefined) )] -# TODO multiline docstring are currently not handled. -##: E125+1:4 +# TODO multiline docstring are currently not handled. E125+1:4? if (""" """): pass diff --git a/test/normalizer_issue_files/E26.py b/test/normalizer_issue_files/E26.py new file mode 100644 index 0000000..4774852 --- /dev/null +++ b/test/normalizer_issue_files/E26.py @@ -0,0 +1,78 @@ +#: E261:4 +pass # an inline comment +#: E261:4 +pass# an inline comment + +# Okay +pass # an inline comment +pass # an inline comment +#: E262:11 +x = x + 1 #Increment x +#: E262:11 +x = x + 1 # Increment x +#: E262:11 +x = y + 1 #: Increment x +#: E265 +#Block comment +a = 1 +#: E265+1 +m = 42 +#! This is important +mx = 42 - 42 + +# Comment without anything is not an issue. +# +# However if there are comments at the end without anything it obviously +# doesn't make too much sense. +#: E262:9 +foo = 1 # + + +#: E266+2:4 E266+5:4 +def how_it_feel(r): + + ### This is a variable ### + a = 42 + + ### Of course it is unused + return + + +#: E266 E266+1 +##if DEBUG: +## logging.error() +#: E266 +######################################### + +# Not at the beginning of a file +#: E265 +#!/usr/bin/env python + +# Okay + +pass # an inline comment +x = x + 1 # Increment x +y = y + 1 #: Increment x + +# Block comment +a = 1 + +# Block comment1 + +# Block comment2 +aaa = 1 + + +# example of docstring (not parsed) +def oof(): + """ + #foo not parsed + """ + + ########################################################################### + # A SEPARATOR # + ########################################################################### + + # ####################################################################### # + # ########################## another separator ########################## # + # ####################################################################### # diff --git a/test/normalizer_issue_files/E30.py b/test/normalizer_issue_files/E30.py index c4f68e8..6853f0c 100644 --- a/test/normalizer_issue_files/E30.py +++ b/test/normalizer_issue_files/E30.py @@ -17,7 +17,6 @@ class X: pass -#!python # -*- coding: utf-8 -*- def a(): pass @@ -106,7 +105,7 @@ def function(): #: E303+3 -#!python +# something diff --git a/test/normalizer_issue_files/E50.py b/test/normalizer_issue_files/E50.py index e1cd124..67fd558 100644 --- a/test/normalizer_issue_files/E50.py +++ b/test/normalizer_issue_files/E50.py @@ -62,8 +62,7 @@ ddd = \ #: E501:67 E225:21 E225:22 very_long_identifiers=and_terrible_whitespace_habits(are_no_excuse+for_long_lines) # -# TODO Long multiline strings are not handled. -##: E501 +# TODO Long multiline strings are not handled. E501? '''multiline string with a long long long long long long long long long long long long long long long long line ''' diff --git a/test/test_pep8.py b/test/test_pep8.py index ec4cd86..e4a243e 100644 --- a/test/test_pep8.py +++ b/test/test_pep8.py @@ -15,7 +15,7 @@ def test_eof_newline(): assert not issues('asdf = 1\n') assert_issue('asdf = 1') - assert_issue('asdf = 1\n#') + assert_issue('asdf = 1\n# foo') assert_issue('# foobar') assert_issue('') assert_issue('foo = 1 # comment') @@ -31,3 +31,8 @@ def test_eof_blankline(): assert_issue('asdf = 1\n\n') assert_issue('# foobar\n\n') assert_issue('\n\n') + +def test_shebang(): + assert not issues('#!\n') + assert not issues('#!/foo\n') + assert not issues('#! python\n')