diff --git a/parso/python/diff.py b/parso/python/diff.py index 8b4ac3c..0973afc 100644 --- a/parso/python/diff.py +++ b/parso/python/diff.py @@ -278,7 +278,7 @@ class DiffParser(object): if operation == 'equal': line_offset = j1 - i1 - self._copy_from_old_parser(line_offset, i2, j2) + self._copy_from_old_parser(line_offset, i1 + 1, i2, j2) elif operation == 'replace': self._parse(until_line=j2) elif operation == 'insert': @@ -319,7 +319,7 @@ class DiffParser(object): if self._module.get_code() != ''.join(lines_new): LOG.warning('parser issue:\n%s\n%s', ''.join(old_lines), ''.join(lines_new)) - def _copy_from_old_parser(self, line_offset, until_line_old, until_line_new): + def _copy_from_old_parser(self, line_offset, start_line_old, until_line_old, until_line_new): last_until_line = -1 while until_line_new > self._nodes_tree.parsed_until_line: parsed_until_line_old = self._nodes_tree.parsed_until_line - line_offset @@ -333,12 +333,18 @@ class DiffParser(object): p_children = line_stmt.parent.children index = p_children.index(line_stmt) - from_ = self._nodes_tree.parsed_until_line + 1 - copied_nodes = self._nodes_tree.copy_nodes( - p_children[index:], - until_line_old, - line_offset - ) + if start_line_old == 1 \ + and p_children[0].get_first_leaf().prefix.startswith(BOM_UTF8_STRING): + # If there's a BOM in the beginning, just reparse. It's too + # complicated to account for it otherwise. + copied_nodes = [] + else: + from_ = self._nodes_tree.parsed_until_line + 1 + copied_nodes = self._nodes_tree.copy_nodes( + p_children[index:], + until_line_old, + line_offset + ) # Match all the nodes that are in the wanted range. if copied_nodes: self._copy_count += 1 diff --git a/test/test_diff_parser.py b/test/test_diff_parser.py index 96d12db..d59ad08 100644 --- a/test/test_diff_parser.py +++ b/test/test_diff_parser.py @@ -1593,6 +1593,14 @@ def test_byte_order_mark2(differ): differ.parse(code + 'x', parsers=1) +def test_byte_order_mark3(differ): + code1 = "\ufeff#\ny\n" + code2 = 'x\n\ufeff#\n\ufeff#\ny\n' + differ.initialize(code1) + differ.parse(code2, expect_error_leaves=True, parsers=3) + differ.parse(code1, parsers=1) + + def test_backslash_insertion(differ): code1 = dedent(''' def f():