diff --git a/jedi/parser/fast.py b/jedi/parser/fast.py index 91a42e25..a69a9d2f 100644 --- a/jedi/parser/fast.py +++ b/jedi/parser/fast.py @@ -278,6 +278,7 @@ class FastParser(use_metaclass(CachedFastParser)): # Use -1, because that indent is always smaller than any other. indent_list = [-1, 0] new_indent = False + parentheses_level = 0 flow_indent = None # All things within flows are simply being ignored. for i, l in enumerate(self._lines): @@ -299,9 +300,8 @@ class FastParser(use_metaclass(CachedFastParser)): # This automatically resets the flow_indent if there was a # dedent or a flow just on one line (with one simple_stmt). new_indent = False - if flow_indent is None: - if current_lines: - yield gen_part() + if flow_indent is None and current_lines and not parentheses_level: + yield gen_part() flow_indent = None # Check lines for functions/classes and split the code there. @@ -310,18 +310,23 @@ class FastParser(use_metaclass(CachedFastParser)): if m: # Strip whitespace and colon from flows as a check. if m.group(1).strip(' \t\r\n:') in FLOWS: - flow_indent = indent + if not parentheses_level: + flow_indent = indent else: if not is_decorator and not just_newlines(current_lines): yield gen_part() is_decorator = '@' == m.group(1) if not is_decorator: + parentheses_level = 0 # The new indent needs to be higher indent_list.append(indent + 1) new_indent = True elif is_decorator: is_decorator = False + parentheses_level += (l.count('(') + l.count('[') + l.count('{') + - l.count(')') - l.count(']') - l.count('}')) + current_lines.append(l) if current_lines: yield gen_part() diff --git a/test/test_parser/test_fast_parser.py b/test/test_parser/test_fast_parser.py index f1023011..360d0eda 100644 --- a/test/test_parser/test_fast_parser.py +++ b/test/test_parser/test_fast_parser.py @@ -334,7 +334,39 @@ def test_open_parentheses(): # however that would require to also break properly at flow level. That is # not possible because of ternary statements and would lead to strange # behavior without much more knowledge. So we just keep it this way. - assert p.number_parsers_used == 1 + assert p.number_parsers_used == 2 + + +def test_strange_parentheses(): + src = dedent(""" + class X(): + a = (1 + if 1 else 2) + def x(): + pass + """) + check_fp(src, 2) + + +def test_backslash(): + src = dedent("""\ + a = 1\ + if 1 else 2 + def x(): + pass + """) + check_fp(src, 2) + + src = dedent("""\ + if 2: + a = 1\ + if 1 else 2 + def y(): + pass + """) + # The dangling if leads to not splitting where we theoretically could + # split. + check_fp(src, 1) def test_incomplete_function():