diff --git a/parso/python/diff.py b/parso/python/diff.py index 396dc9e..f901813 100644 --- a/parso/python/diff.py +++ b/parso/python/diff.py @@ -578,8 +578,14 @@ class _NodesTree(object): Returns the number of tree nodes that were copied. """ - if tree_nodes[0].type == 'error_leaf' and tree_nodes[0].token_type == 'INDENT': - # Avoid copying error indents. Just parse them again. + i = 0 + for i, n in enumerate(tree_nodes): + if tree_nodes[0].type not in ('INDENT', 'DEDENT'): + break + + if tree_nodes[i].type in ('error_leaf', 'error_node'): + # Avoid copying errors in the beginning. Can lead to a lot of + # issues. return [] self._get_insertion_node(tree_nodes[0]) @@ -622,10 +628,6 @@ class _NodesTree(object): new_nodes.append(node) - while new_nodes and new_nodes[0].type == 'error_leaf' \ - and new_nodes[0].token_type in _INDENTATION_TOKENS: - new_nodes.pop(0) - if not new_nodes: return [], working_stack, prefix diff --git a/test/test_diff_parser.py b/test/test_diff_parser.py index 93014e0..9accde8 100644 --- a/test/test_diff_parser.py +++ b/test/test_diff_parser.py @@ -205,7 +205,7 @@ def test_open_parentheses(differ): differ.parse(new_code, parsers=1, expect_error_leaves=True) new_code = 'a = 1\n' + new_code - differ.parse(new_code, copies=1, parsers=1, expect_error_leaves=True) + differ.parse(new_code, parsers=2, expect_error_leaves=True) func += 'def other_func():\n pass\n' differ.initialize('isinstance(\n' + func) @@ -502,7 +502,7 @@ def test_endmarker_newline(differ): code2 = code1.replace('codet', 'coded') differ.initialize(code1) - differ.parse(code2, parsers=1, copies=2, expect_error_leaves=True) + differ.parse(code2, parsers=2, copies=1, expect_error_leaves=True) def test_newlines_at_end(differ): @@ -1099,7 +1099,7 @@ def test_all_sorts_of_indentation(differ): end ''') differ.initialize(code1) - differ.parse(code2, copies=2, parsers=3, expect_error_leaves=True) + differ.parse(code2, copies=1, parsers=4, expect_error_leaves=True) differ.parse(code1, copies=1, parsers=3) code3 = dedent('''\ @@ -1127,4 +1127,24 @@ def test_dont_copy_dedents_in_beginning(differ): ''') differ.initialize(code1) differ.parse(code2, copies=1, parsers=1, expect_error_leaves=True) - differ.parse(code1, copies=1, parsers=1) + differ.parse(code1, parsers=2) + + +def test_dont_copy_error_leaves(differ): + code1 = dedent('''\ + def f(n): + x + if 2: + 3 + ''') + code2 = dedent('''\ + def f(n): + def if 1: + indent + x + if 2: + 3 + ''') + differ.initialize(code1) + differ.parse(code2, parsers=1, expect_error_leaves=True) + differ.parse(code1, parsers=2)