mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-06 12:54:29 +08:00
Merge pull request #188 from davidhalter/line-ending
Fix line endings support at various locations
This commit is contained in:
@@ -74,7 +74,7 @@ class BracketNode(IndentationNode):
|
||||
parent_indentation = n.indentation
|
||||
|
||||
next_leaf = leaf.get_next_leaf()
|
||||
if '\n' in next_leaf.prefix:
|
||||
if '\n' in next_leaf.prefix or '\r' in next_leaf.prefix:
|
||||
# This implies code like:
|
||||
# foobarbaz(
|
||||
# a,
|
||||
@@ -116,7 +116,7 @@ class ImplicitNode(BracketNode):
|
||||
self.type = IndentationTypes.IMPLICIT
|
||||
|
||||
next_leaf = leaf.get_next_leaf()
|
||||
if leaf == ':' and '\n' not in next_leaf.prefix:
|
||||
if leaf == ':' and '\n' not in next_leaf.prefix and '\r' not in next_leaf.prefix:
|
||||
self.indentation += ' '
|
||||
|
||||
|
||||
@@ -216,8 +216,8 @@ class PEP8Normalizer(ErrorFinder):
|
||||
endmarker = node.children[-1]
|
||||
prev = endmarker.get_previous_leaf()
|
||||
prefix = endmarker.prefix
|
||||
if (not prefix.endswith('\n') and (
|
||||
prefix or prev is None or prev.value != '\n')):
|
||||
if (not prefix.endswith('\n') and not prefix.endswith('\r') and (
|
||||
prefix or prev is None or prev.value not in {'\n', '\r\n', '\r'})):
|
||||
self.add_issue(endmarker, 292, "No newline at end of file")
|
||||
|
||||
if typ in _IMPORT_TYPES:
|
||||
@@ -465,7 +465,8 @@ class PEP8Normalizer(ErrorFinder):
|
||||
+ self._config.indentation:
|
||||
self.add_issue(part, 129, "Line with same indent as next logical block")
|
||||
elif indentation != should_be_indentation:
|
||||
if not self._check_tabs_spaces(spacing) and part.value != '\n':
|
||||
if not self._check_tabs_spaces(spacing) and part.value not in \
|
||||
{'\n', '\r\n', '\r'}:
|
||||
if value in '])}':
|
||||
if node.type == IndentationTypes.VERTICAL_BRACKET:
|
||||
self.add_issue(
|
||||
@@ -652,7 +653,8 @@ class PEP8Normalizer(ErrorFinder):
|
||||
else:
|
||||
prev_spacing = self._previous_spacing
|
||||
if prev in _ALLOW_SPACE and spaces != prev_spacing.value \
|
||||
and '\n' not in self._previous_leaf.prefix:
|
||||
and '\n' not in self._previous_leaf.prefix \
|
||||
and '\r' not in self._previous_leaf.prefix:
|
||||
message = "Whitespace before operator doesn't match with whitespace after"
|
||||
self.add_issue(spacing, 229, message)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class PrefixPart:
|
||||
|
||||
@property
|
||||
def end_pos(self) -> Tuple[int, int]:
|
||||
if self.value.endswith('\n'):
|
||||
if self.value.endswith('\n') or self.value.endswith('\r'):
|
||||
return self.start_pos[0] + 1, 0
|
||||
if self.value == unicode_bom:
|
||||
# The bom doesn't have a length at the start of a Python file.
|
||||
@@ -50,8 +50,8 @@ class PrefixPart:
|
||||
|
||||
|
||||
_comment = r'#[^\n\r\f]*'
|
||||
_backslash = r'\\\r?\n'
|
||||
_newline = r'\r?\n'
|
||||
_backslash = r'\\\r?\n|\\\r'
|
||||
_newline = r'\r?\n|\r'
|
||||
_form_feed = r'\f'
|
||||
_only_spacing = '$'
|
||||
_spacing = r'[ \t]*'
|
||||
@@ -94,7 +94,7 @@ def split_prefix(leaf, start_pos):
|
||||
bom = True
|
||||
|
||||
start = match.end(0)
|
||||
if value.endswith('\n'):
|
||||
if value.endswith('\n') or value.endswith('\r'):
|
||||
line += 1
|
||||
column = -start
|
||||
|
||||
|
||||
@@ -548,7 +548,7 @@ def tokenize_lines(
|
||||
additional_prefix = prefix + token
|
||||
new_line = True
|
||||
elif initial == '#': # Comments
|
||||
assert not token.endswith("\n")
|
||||
assert not token.endswith("\n") and not token.endswith("\r")
|
||||
if fstring_stack and fstring_stack[-1].is_in_expr():
|
||||
# `#` is not allowed in f-string expressions
|
||||
yield PythonToken(ERRORTOKEN, initial, spos, prefix)
|
||||
|
||||
@@ -92,7 +92,7 @@ def python_bytes_to_unicode(
|
||||
# UTF-8 byte-order mark
|
||||
return 'utf-8'
|
||||
|
||||
first_two_lines = re.match(br'(?:[^\n]*\n){0,2}', source).group(0)
|
||||
first_two_lines = re.match(br'(?:[^\r\n]*(?:\r\n|\r|\n)){0,2}', source).group(0)
|
||||
possible_encoding = re.search(br"coding[=:]\s*([-\w.]+)",
|
||||
first_two_lines)
|
||||
if possible_encoding:
|
||||
|
||||
@@ -15,6 +15,8 @@ def test_eof_newline():
|
||||
assert issue.code == 292
|
||||
|
||||
assert not issues('asdf = 1\n')
|
||||
assert not issues('asdf = 1\r\n')
|
||||
assert not issues('asdf = 1\r')
|
||||
assert_issue('asdf = 1')
|
||||
assert_issue('asdf = 1\n# foo')
|
||||
assert_issue('# foobar')
|
||||
|
||||
@@ -19,6 +19,7 @@ unicode_bom = BOM_UTF8.decode('utf-8')
|
||||
(' \f ', ['\f', ' ']),
|
||||
(' \f ', ['\f', ' ']),
|
||||
(' \r\n', ['\r\n', '']),
|
||||
(' \r', ['\r', '']),
|
||||
('\\\n', ['\\\n', '']),
|
||||
('\\\r\n', ['\\\r\n', '']),
|
||||
('\t\t\n\t', ['\n', '\t']),
|
||||
@@ -34,7 +35,7 @@ def test_simple_prefix_splitting(string, tokens):
|
||||
assert pt.value == expected
|
||||
|
||||
# Calculate the estimated end_pos
|
||||
if expected.endswith('\n'):
|
||||
if expected.endswith('\n') or expected.endswith('\r'):
|
||||
end_pos = start_pos[0] + 1, 0
|
||||
else:
|
||||
end_pos = start_pos[0], start_pos[1] + len(expected) + len(pt.spacing)
|
||||
|
||||
@@ -74,6 +74,10 @@ def test_utf8_bom():
|
||||
('code', 'errors'), [
|
||||
(b'# coding: wtf-12\nfoo', 'strict'),
|
||||
(b'# coding: wtf-12\nfoo', 'replace'),
|
||||
(b'# coding: wtf-12\r\nfoo', 'strict'),
|
||||
(b'# coding: wtf-12\r\nfoo', 'replace'),
|
||||
(b'# coding: wtf-12\rfoo', 'strict'),
|
||||
(b'# coding: wtf-12\rfoo', 'replace'),
|
||||
]
|
||||
)
|
||||
def test_bytes_to_unicode_failing_encoding(code, errors):
|
||||
|
||||
Reference in New Issue
Block a user