mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-07 05:14:29 +08:00
Fix comment issues (E26x).
This commit is contained in:
@@ -64,6 +64,9 @@ class Issue(object):
|
|||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash((self.code, self.start_pos))
|
return hash((self.code, self.start_pos))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<%s: %s>' % (self.__class__.__name__, self.code)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Rule(object):
|
class Rule(object):
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import re
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from parso.normalizer import Normalizer, Rule, NormalizerConfig
|
from parso.normalizer import Normalizer, Rule, NormalizerConfig
|
||||||
from parso.python.prefix import PrefixPart
|
|
||||||
|
|
||||||
|
|
||||||
_IMPORT_TYPES = ('import_name', 'import_from')
|
_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')
|
_NON_STAR_TYPES = ('term', 'import_from', 'power')
|
||||||
_OPENING_BRACKETS = '(', '[', '{'
|
_OPENING_BRACKETS = '(', '[', '{'
|
||||||
_CLOSING_BRACKETS = ')', ']', '}'
|
_CLOSING_BRACKETS = ')', ']', '}'
|
||||||
# TODO ~ << >> & | ^
|
|
||||||
_FACTOR = '+', '-', '~'
|
_FACTOR = '+', '-', '~'
|
||||||
_ALLOW_SPACE = '*', '+', '-', '**', '/', '//', '@'
|
_ALLOW_SPACE = '*', '+', '-', '**', '/', '//', '@'
|
||||||
_BITWISE_OPERATOR = '<<', '>>', '|', '&', '^'
|
_BITWISE_OPERATOR = '<<', '>>', '|', '&', '^'
|
||||||
@@ -392,6 +390,18 @@ class PEP8Normalizer(Normalizer):
|
|||||||
node = self._indentation_tos
|
node = self._indentation_tos
|
||||||
|
|
||||||
if type_ == 'comment':
|
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)
|
self._reset_newlines(spacing, actual_leaf, is_comment=True)
|
||||||
elif type_ == 'newline':
|
elif type_ == 'newline':
|
||||||
if self._newline_count > self._get_wanted_blank_lines_count():
|
if self._newline_count > self._get_wanted_blank_lines_count():
|
||||||
@@ -420,7 +430,6 @@ class PEP8Normalizer(Normalizer):
|
|||||||
spacing,
|
spacing,
|
||||||
parent=self._indentation_tos
|
parent=self._indentation_tos
|
||||||
)
|
)
|
||||||
|
|
||||||
elif self._on_newline:
|
elif self._on_newline:
|
||||||
indentation = spacing.value
|
indentation = spacing.value
|
||||||
if node.type == IndentationTypes.BACKSLASH \
|
if node.type == IndentationTypes.BACKSLASH \
|
||||||
@@ -558,7 +567,8 @@ class PEP8Normalizer(Normalizer):
|
|||||||
if '\t' in spaces:
|
if '\t' in spaces:
|
||||||
self.add_issue(223, 'Used tab to separate tokens', spacing)
|
self.add_issue(223, 'Used tab to separate tokens', spacing)
|
||||||
elif type_ == 'comment':
|
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':
|
elif type_ == 'newline':
|
||||||
add_if_spaces(291, 'Trailing whitespace', spacing)
|
add_if_spaces(291, 'Trailing whitespace', spacing)
|
||||||
elif len(spaces) > 1:
|
elif len(spaces) > 1:
|
||||||
@@ -707,6 +717,7 @@ class PEP8NormalizerConfig(NormalizerConfig):
|
|||||||
self.closing_bracket_hanging_indentation = ''
|
self.closing_bracket_hanging_indentation = ''
|
||||||
self.break_after_binary = False
|
self.break_after_binary = False
|
||||||
self.max_characters = 79
|
self.max_characters = 79
|
||||||
|
self.spaces_before_comment = 2
|
||||||
|
|
||||||
|
|
||||||
@PEP8NormalizerConfig.register_rule
|
@PEP8NormalizerConfig.register_rule
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ if bar:
|
|||||||
"to match that of the opening "
|
"to match that of the opening "
|
||||||
"bracket's line"
|
"bracket's line"
|
||||||
)
|
)
|
||||||
#
|
|
||||||
# you want vertical alignment, so use a parens
|
# you want vertical alignment, so use a parens
|
||||||
#: E101+3
|
#: E101+3
|
||||||
if ((foo.bar("baz") and
|
if ((foo.bar("baz") and
|
||||||
@@ -83,7 +83,6 @@ if length > options.max_line_length:
|
|||||||
"E501 line too long (%d characters)" % length
|
"E501 line too long (%d characters)" % length
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
#: E101+1 E101+2
|
#: E101+1 E101+2
|
||||||
if os.path.exists(os.path.join(path, PEP8_BIN)):
|
if os.path.exists(os.path.join(path, PEP8_BIN)):
|
||||||
cmd = ([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
|
will get no warning
|
||||||
even though the noqa comment is not immediately after the string
|
even though the noqa comment is not immediately after the string
|
||||||
''' + foo # noqa
|
''' + foo # noqa
|
||||||
#
|
|
||||||
#: E101+2
|
#: E101+2
|
||||||
if foo is None and bar is "frop" and \
|
if foo is None and bar is "frop" and \
|
||||||
blah == 'yeah':
|
blah == 'yeah':
|
||||||
blah = 'yeahnah'
|
blah = 'yeahnah'
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
#: E101+1 E101+2 E101+3
|
#: E101+1 E101+2 E101+3
|
||||||
if True:
|
if True:
|
||||||
foo(
|
foo(
|
||||||
|
|||||||
@@ -49,9 +49,6 @@ a = (123,
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
if start[1] > end_col and not (
|
if start[1] > end_col and not (
|
||||||
over_indent == 4 and indent_next):
|
over_indent == 4 and indent_next):
|
||||||
return (0, "E121 continuation line over-"
|
return (0, "E121 continuation line over-"
|
||||||
@@ -91,7 +88,6 @@ print "hello", (
|
|||||||
foo = long_function_name(var_one, var_two,
|
foo = long_function_name(var_one, var_two,
|
||||||
var_three, var_four)
|
var_three, var_four)
|
||||||
|
|
||||||
#
|
|
||||||
# Extra indentation is not necessary.
|
# Extra indentation is not necessary.
|
||||||
foo = long_function_name(
|
foo = long_function_name(
|
||||||
var_one, var_two,
|
var_one, var_two,
|
||||||
@@ -173,8 +169,6 @@ foo = my.func({
|
|||||||
}, "baz")
|
}, "baz")
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
fooff(aaaa,
|
fooff(aaaa,
|
||||||
cca(
|
cca(
|
||||||
vvv,
|
vvv,
|
||||||
@@ -189,7 +183,6 @@ fooff(aaaa,
|
|||||||
aaa,
|
aaa,
|
||||||
dadd),
|
dadd),
|
||||||
"visual indentation is not a multiple of four",)
|
"visual indentation is not a multiple of four",)
|
||||||
#
|
|
||||||
|
|
||||||
if bar:
|
if bar:
|
||||||
return (
|
return (
|
||||||
@@ -198,7 +191,7 @@ if bar:
|
|||||||
"to match that of the opening "
|
"to match that of the opening "
|
||||||
"bracket's line"
|
"bracket's line"
|
||||||
)
|
)
|
||||||
#
|
|
||||||
# you want vertical alignment, so use a parens
|
# you want vertical alignment, so use a parens
|
||||||
if ((foo.bar("baz") and
|
if ((foo.bar("baz") and
|
||||||
foo.bar("frop")
|
foo.bar("frop")
|
||||||
@@ -333,9 +326,6 @@ rv.update(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
event_obj.write(cursor, user_id, {
|
event_obj.write(cursor, user_id, {
|
||||||
'user': user,
|
'user': user,
|
||||||
'summary': text,
|
'summary': text,
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ def unicode2html(s):
|
|||||||
.replace('\n', '<br>\n'))
|
.replace('\n', '<br>\n'))
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
parser.add_option('--count', action='store_true',
|
parser.add_option('--count', action='store_true',
|
||||||
help="print total number of errors and warnings "
|
help="print total number of errors and warnings "
|
||||||
"to standard error and set exit code to 1 if "
|
"to standard error and set exit code to 1 if "
|
||||||
@@ -75,9 +74,6 @@ add_option('--count',
|
|||||||
"total is not null")
|
"total is not null")
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
help = ("print total number of errors " +
|
help = ("print total number of errors " +
|
||||||
"to standard error")
|
"to standard error")
|
||||||
|
|
||||||
@@ -163,7 +159,6 @@ troublesome_hash = {
|
|||||||
"when you're indented": "stringwithalongtoken you don't want to break",
|
"when you're indented": "stringwithalongtoken you don't want to break",
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
d = dict('foo',
|
d = dict('foo',
|
||||||
help="exclude files or directories which match these "
|
help="exclude files or directories which match these "
|
||||||
"comma separated patterns (default: %s)" %
|
"comma separated patterns (default: %s)" %
|
||||||
@@ -207,7 +202,7 @@ d = { # comment
|
|||||||
if a > b and \
|
if a > b and \
|
||||||
c > d:
|
c > d:
|
||||||
moo_like_a_cow()
|
moo_like_a_cow()
|
||||||
#
|
|
||||||
my_list = [
|
my_list = [
|
||||||
1, 2, 3,
|
1, 2, 3,
|
||||||
4, 5, 6,
|
4, 5, 6,
|
||||||
@@ -249,7 +244,7 @@ bar(
|
|||||||
bar(
|
bar(
|
||||||
1).zap(
|
1).zap(
|
||||||
2)
|
2)
|
||||||
#
|
|
||||||
if True:
|
if True:
|
||||||
|
|
||||||
def example_issue254():
|
def example_issue254():
|
||||||
|
|||||||
@@ -86,8 +86,7 @@ if True:
|
|||||||
),
|
),
|
||||||
dict(name=token.undefined)
|
dict(name=token.undefined)
|
||||||
)]
|
)]
|
||||||
# TODO multiline docstring are currently not handled.
|
# TODO multiline docstring are currently not handled. E125+1:4?
|
||||||
##: E125+1:4
|
|
||||||
if ("""
|
if ("""
|
||||||
"""):
|
"""):
|
||||||
pass
|
pass
|
||||||
|
|||||||
78
test/normalizer_issue_files/E26.py
Normal file
78
test/normalizer_issue_files/E26.py
Normal file
@@ -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 ########################## #
|
||||||
|
# ####################################################################### #
|
||||||
@@ -17,7 +17,6 @@ class X:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
#!python
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
def a():
|
def a():
|
||||||
pass
|
pass
|
||||||
@@ -106,7 +105,7 @@ def function():
|
|||||||
|
|
||||||
|
|
||||||
#: E303+3
|
#: E303+3
|
||||||
#!python
|
# something
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -62,8 +62,7 @@ ddd = \
|
|||||||
#: E501:67 E225:21 E225:22
|
#: E501:67 E225:21 E225:22
|
||||||
very_long_identifiers=and_terrible_whitespace_habits(are_no_excuse+for_long_lines)
|
very_long_identifiers=and_terrible_whitespace_habits(are_no_excuse+for_long_lines)
|
||||||
#
|
#
|
||||||
# TODO Long multiline strings are not handled.
|
# TODO Long multiline strings are not handled. E501?
|
||||||
##: E501
|
|
||||||
'''multiline string
|
'''multiline string
|
||||||
with a long long long long long long long long long long long long long long long long line
|
with a long long long long long long long long long long long long long long long long line
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ def test_eof_newline():
|
|||||||
|
|
||||||
assert not issues('asdf = 1\n')
|
assert not issues('asdf = 1\n')
|
||||||
assert_issue('asdf = 1')
|
assert_issue('asdf = 1')
|
||||||
assert_issue('asdf = 1\n#')
|
assert_issue('asdf = 1\n# foo')
|
||||||
assert_issue('# foobar')
|
assert_issue('# foobar')
|
||||||
assert_issue('')
|
assert_issue('')
|
||||||
assert_issue('foo = 1 # comment')
|
assert_issue('foo = 1 # comment')
|
||||||
@@ -31,3 +31,8 @@ def test_eof_blankline():
|
|||||||
assert_issue('asdf = 1\n\n')
|
assert_issue('asdf = 1\n\n')
|
||||||
assert_issue('# foobar\n\n')
|
assert_issue('# foobar\n\n')
|
||||||
assert_issue('\n\n')
|
assert_issue('\n\n')
|
||||||
|
|
||||||
|
def test_shebang():
|
||||||
|
assert not issues('#!\n')
|
||||||
|
assert not issues('#!/foo\n')
|
||||||
|
assert not issues('#! python\n')
|
||||||
|
|||||||
Reference in New Issue
Block a user