diff --git a/parso/python/diff.py b/parso/python/diff.py index 6495557..ba1c940 100644 --- a/parso/python/diff.py +++ b/parso/python/diff.py @@ -726,6 +726,17 @@ class _NodesTree(object): if _func_or_class_has_suite(node): new_nodes.append(node) break + try: + c = node.children + except AttributeError: + pass + else: + # This case basically appears with error recovery of one line + # suites like `def foo(): bar.-`. In this case we might not + # include a newline in the statement and we need to take care + # of that. + if c[-1].type in ('error_leaf', 'error_node'): + break new_nodes.append(node) diff --git a/test/test_diff_parser.py b/test/test_diff_parser.py index ea9632b..ea2a692 100644 --- a/test/test_diff_parser.py +++ b/test/test_diff_parser.py @@ -1706,3 +1706,25 @@ def test_backslash_with_imports(differ): differ.initialize(code1) differ.parse(code2, parsers=1) differ.parse(code1, parsers=1) + + +def test_one_line_function_error_recovery(differ): + code1 = dedent('''\ + class X: + x + def y(): word """ + # a + # b + c(self) + ''') + code2 = dedent('''\ + class X: + x + def y(): word """ + # a + # b + c(\x01+self) + ''') + + differ.initialize(code1) + differ.parse(code2, parsers=1, copies=1, expect_error_leaves=True)