mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-06 21:04:29 +08:00
Implement E101. No mixing of tabs and spaces in indentation.
This commit is contained in:
@@ -16,6 +16,7 @@ class Normalizer(object):
|
|||||||
def add_issue(self, code, message, node):
|
def add_issue(self, code, message, node):
|
||||||
issue = Issue(node, code, message)
|
issue = Issue(node, code, message)
|
||||||
self.issues.append(issue)
|
self.issues.append(issue)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class NormalizerConfig(object):
|
class NormalizerConfig(object):
|
||||||
|
|||||||
@@ -13,10 +13,14 @@ class CompressNormalizer(Normalizer):
|
|||||||
|
|
||||||
|
|
||||||
class Comment(object):
|
class Comment(object):
|
||||||
def __init__(self, comment_token, indentation):
|
def __init__(self, comment_part, indentation_part):
|
||||||
self.comment_token = comment_token
|
self.comment_part = comment_part
|
||||||
self.indentation = indentation
|
self.indentation_part = indentation_part
|
||||||
self.start_pos = self.comment_token.start_pos
|
if indentation_part is None:
|
||||||
|
self.indentation = ''
|
||||||
|
else:
|
||||||
|
self.indentation = indentation_part.value
|
||||||
|
self.start_pos = self.comment_part.start_pos
|
||||||
|
|
||||||
|
|
||||||
class WhitespaceInfo(object):
|
class WhitespaceInfo(object):
|
||||||
@@ -33,19 +37,24 @@ class WhitespaceInfo(object):
|
|||||||
'''
|
'''
|
||||||
self.has_backslash = False
|
self.has_backslash = False
|
||||||
self.comments = []
|
self.comments = []
|
||||||
indentation = ''
|
indentation_part = None
|
||||||
for part in parts:
|
for part in parts:
|
||||||
if part.type == 'backslash':
|
if part.type == 'backslash':
|
||||||
self.has_backslash = True
|
self.has_backslash = True
|
||||||
|
|
||||||
if part.type == 'comment':
|
if part.type == 'comment':
|
||||||
self.comments.append(Comment(part, indentation))
|
self.comments.append(Comment(part, indentation_part))
|
||||||
|
|
||||||
if part.type == 'indentation':
|
if part.type == 'indentation':
|
||||||
indentation = part.value
|
indentation_part = part
|
||||||
else:
|
else:
|
||||||
indentation = ''
|
indentation_part = None
|
||||||
self.indentation = indentation
|
|
||||||
|
if indentation_part is None:
|
||||||
|
self.indentation = ''
|
||||||
|
else:
|
||||||
|
self.indentation = indentation_part.value
|
||||||
|
self.indentation_part = indentation_part
|
||||||
|
|
||||||
self.newline_count = 2
|
self.newline_count = 2
|
||||||
self.trailing_whitespace = []
|
self.trailing_whitespace = []
|
||||||
@@ -63,6 +72,13 @@ class PEP8Normalizer(Normalizer):
|
|||||||
self._last_indentation_level = 0
|
self._last_indentation_level = 0
|
||||||
self._on_newline = True
|
self._on_newline = True
|
||||||
|
|
||||||
|
if ' ' in config.indentation:
|
||||||
|
self._indentation_type = 'spaces'
|
||||||
|
self._wrong_indentation_char = '\t'
|
||||||
|
else:
|
||||||
|
self._indentation_type = 'tabs'
|
||||||
|
self._wrong_indentation_char = ' '
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def visit_node(self, node):
|
def visit_node(self, node):
|
||||||
typ = node.type
|
typ = node.type
|
||||||
@@ -129,17 +145,25 @@ class PEP8Normalizer(Normalizer):
|
|||||||
if typ == 'suite':
|
if typ == 'suite':
|
||||||
self._indentation_level -= 1
|
self._indentation_level -= 1
|
||||||
|
|
||||||
|
def _check_tabs_spaces(self, leaf, indentation):
|
||||||
|
if self._wrong_indentation_char in indentation:
|
||||||
|
self.add_issue(101, 'Indentation contains ' + self._indentation_type, leaf)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def normalize(self, leaf):
|
def normalize(self, leaf):
|
||||||
info = WhitespaceInfo(leaf)
|
info = WhitespaceInfo(leaf)
|
||||||
should_be_indenation = self._indentation_level * self._config.indentation
|
should_be_indenation = self._indentation_level * self._config.indentation
|
||||||
if self._on_newline:
|
if self._on_newline:
|
||||||
if info.indentation != should_be_indenation:
|
if info.indentation != should_be_indenation:
|
||||||
self.add_issue(111, 'Indentation is not a multiple of four', leaf)
|
if not self._check_tabs_spaces(info.indentation_part, info.indentation):
|
||||||
|
s = '%s %s' % (len(self._config.indentation), self._indentation_type)
|
||||||
|
self.add_issue(111, 'Indentation is not a multiple of ' + s, leaf)
|
||||||
|
|
||||||
first = True
|
first = True
|
||||||
for comment in info.comments:
|
for comment in info.comments:
|
||||||
if first and not self._on_newline:
|
if first and not self._on_newline:
|
||||||
continue
|
continue
|
||||||
first = False
|
first = False
|
||||||
|
|
||||||
actual_len = len(comment.indentation)
|
actual_len = len(comment.indentation)
|
||||||
@@ -154,12 +178,13 @@ class PEP8Normalizer(Normalizer):
|
|||||||
if comment.indentation == should_be_indenation:
|
if comment.indentation == should_be_indenation:
|
||||||
self._last_indentation_level = i
|
self._last_indentation_level = i
|
||||||
else:
|
else:
|
||||||
if actual_len < should_len:
|
if not self._check_tabs_spaces(comment.indentation_part, comment.indentation):
|
||||||
self.add_issue(115, 'Expected an indented block (comment)', comment)
|
if actual_len < should_len:
|
||||||
elif actual_len > should_len:
|
self.add_issue(115, 'Expected an indented block (comment)', comment)
|
||||||
self.add_issue(116, 'Unexpected indentation (comment)', comment)
|
elif actual_len > should_len:
|
||||||
else:
|
self.add_issue(116, 'Unexpected indentation (comment)', comment)
|
||||||
self.add_issue(114, 'indentation is not a multiple of four (comment)', comment)
|
else:
|
||||||
|
self.add_issue(114, 'indentation is not a multiple of four (comment)', comment)
|
||||||
|
|
||||||
self._on_newline = True
|
self._on_newline = True
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,14 @@ class PrefixPart(object):
|
|||||||
return self.start_pos[0] + 1, 0
|
return self.start_pos[0] + 1, 0
|
||||||
return self.start_pos[0], self.start_pos[1] + len(self.value)
|
return self.start_pos[0], self.start_pos[1] + len(self.value)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '%s(%s, %s, %s)' % (
|
||||||
|
self.__class__.__name__,
|
||||||
|
self.type,
|
||||||
|
repr(self.value),
|
||||||
|
self.start_pos
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
_comment = r'#[^\n\r\f]*'
|
_comment = r'#[^\n\r\f]*'
|
||||||
_backslash = r'\\\r?\n'
|
_backslash = r'\\\r?\n'
|
||||||
|
|||||||
44
test/normalizer_issue_files/E10.py
Normal file
44
test/normalizer_issue_files/E10.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
for a in 'abc':
|
||||||
|
for b in 'xyz':
|
||||||
|
print a # indented with 8 spaces
|
||||||
|
#: W101:0
|
||||||
|
print b # indented with 1 tab
|
||||||
|
if True:
|
||||||
|
#: W101:0
|
||||||
|
pass
|
||||||
|
|
||||||
|
change_2_log = \
|
||||||
|
"""Change 2 by slamb@testclient on 2006/04/13 21:46:23
|
||||||
|
|
||||||
|
creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
p4change = {
|
||||||
|
2: change_2_log,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestP4Poller(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.setUpGetProcessOutput()
|
||||||
|
return self.setUpChangeSource()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#
|
||||||
|
if True:
|
||||||
|
#: E101:0
|
||||||
|
foo(1,
|
||||||
|
2)
|
||||||
|
|
||||||
|
def test_keys(self):
|
||||||
|
"""areas.json - All regions are accounted for."""
|
||||||
|
expected = set([
|
||||||
|
u'Norrbotten',
|
||||||
|
u'V\xe4sterbotten',
|
||||||
|
])
|
||||||
|
if True:
|
||||||
|
print("""
|
||||||
|
tab at start of this line
|
||||||
|
""")
|
||||||
@@ -20,7 +20,7 @@ def collect_errors(code):
|
|||||||
code, _, add_indent = code.partition(':')
|
code, _, add_indent = code.partition(':')
|
||||||
column = int(add_indent)
|
column = int(add_indent)
|
||||||
|
|
||||||
yield "%s@(%s,%s)" % (code, line_nr + 1, column)
|
yield "%s@(%s,%s)" % (code[1:], line_nr + 1, column)
|
||||||
|
|
||||||
|
|
||||||
def test_normalizer_issue(normalizer_issue_file):
|
def test_normalizer_issue(normalizer_issue_file):
|
||||||
@@ -32,7 +32,7 @@ def test_normalizer_issue(normalizer_issue_file):
|
|||||||
module = parso.parse(code)
|
module = parso.parse(code)
|
||||||
issues = module._get_normalizer_issues()
|
issues = module._get_normalizer_issues()
|
||||||
|
|
||||||
i = set("E%s@(%s,%s)" % (i.code, i.start_pos[0], i.start_pos[1]) for i in issues)
|
i = set("%s@(%s,%s)" % (i.code, i.start_pos[0], i.start_pos[1]) for i in issues)
|
||||||
d = set(desired)
|
d = set(desired)
|
||||||
assert i == d, dedent("""
|
assert i == d, dedent("""
|
||||||
Test %r failed (%s of %s passed).
|
Test %r failed (%s of %s passed).
|
||||||
|
|||||||
Reference in New Issue
Block a user