##// END OF EJS Templates
A refactor to check_complete to pass the test cases.
Tony Fast -
Show More
@@ -470,9 +470,12 b' def make_tokens_by_line(lines):'
470 except tokenize.TokenError:
470 except tokenize.TokenError:
471 # Input ended in a multiline string or expression. That's OK for us.
471 # Input ended in a multiline string or expression. That's OK for us.
472 pass
472 pass
473
474
473 if not tokens_by_line[-1]:
475 if not tokens_by_line[-1]:
474 tokens_by_line.pop()
476 tokens_by_line.pop()
475
477
478
476 return tokens_by_line
479 return tokens_by_line
477
480
478 def show_linewise_tokens(s: str):
481 def show_linewise_tokens(s: str):
@@ -579,7 +582,24 b' class TransformerManager:'
579 The number of spaces by which to indent the next line of code. If
582 The number of spaces by which to indent the next line of code. If
580 status is not 'incomplete', this is None.
583 status is not 'incomplete', this is None.
581 """
584 """
585 # Remember if the lines ends in a new line.
586 ends_with_newline = False
587 for character in reversed(cell):
588 if character == '\n':
589 ends_with_newline = True
590 break
591 elif character.strip():
592 break
593 else:
594 continue
595
596 if ends_with_newline:
597 # Append an newline for consistent tokenization
598 # See https://bugs.python.org/issue33899
599 cell += '\n'
600
582 lines = cell.splitlines(keepends=True)
601 lines = cell.splitlines(keepends=True)
602
583 if not lines:
603 if not lines:
584 return 'complete', None
604 return 'complete', None
585
605
@@ -608,6 +628,7 b' class TransformerManager:'
608 return 'invalid', None
628 return 'invalid', None
609
629
610 tokens_by_line = make_tokens_by_line(lines)
630 tokens_by_line = make_tokens_by_line(lines)
631
611 if not tokens_by_line:
632 if not tokens_by_line:
612 return 'incomplete', find_last_indent(lines)
633 return 'incomplete', find_last_indent(lines)
613
634
@@ -615,30 +636,33 b' class TransformerManager:'
615 # We're in a multiline string or expression
636 # We're in a multiline string or expression
616 return 'incomplete', find_last_indent(lines)
637 return 'incomplete', find_last_indent(lines)
617
638
618 if len(tokens_by_line[-1]) == 1:
639 newline_types = {tokenize.NEWLINE, tokenize.COMMENT, tokenize.ENDMARKER}
619 return 'incomplete', find_last_indent(lines)
640
620 # Find the last token on the previous line that's not NEWLINE or COMMENT
641 # Remove newline_types for the list of tokens
621 toks_last_line = tokens_by_line[-1]
642 while len(tokens_by_line) > 1 and len(tokens_by_line[-1]) == 1 \
622 ix = len(tokens_by_line) - 1
643 and tokens_by_line[-1][-1].type in newline_types:
644 tokens_by_line.pop()
623
645
646 last_line_token = tokens_by_line[-1]
624
647
625 while ix >= 0 and toks_last_line[-1].type in {tokenize.NEWLINE,
648 while tokens_by_line[-1][-1].type in newline_types:
626 tokenize.COMMENT}:
649 last_line_token = tokens_by_line[-1].pop()
627 ix -= 1
650
628 if tokens_by_line[ix][-2].string == ':':
651 if len(last_line_token) == 1 and not last_line_token[-1]:
652 return 'incomplete', 0
653
654 if last_line_token[-1].string == ':':
629 # The last line starts a block (e.g. 'if foo:')
655 # The last line starts a block (e.g. 'if foo:')
630 ix = 0
656 ix = 0
631 while toks_last_line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
657 while last_line_token[ix].type \
658 in {tokenize.INDENT, tokenize.DEDENT}:
632 ix += 1
659 ix += 1
633 indent = toks_last_line[ix].start[1]
660
661 indent = last_line_token[ix].start[1]
634 return 'incomplete', indent + 4
662 return 'incomplete', indent + 4
635 if tokens_by_line[ix][-2].string == '\\':
636 if not tokens_by_line[ix][-2].line.endswith('\\'):
637 return 'invalid', None
638
663
639 # If there's a blank line at the end, assume we're ready to execute
664 if last_line_token[-1].line.endswith('\\'):
640 if not lines[-1].strip():
665 return 'incomplete', None
641 return 'complete', None
642
666
643 # At this point, our checks think the code is complete (or invalid).
667 # At this point, our checks think the code is complete (or invalid).
644 # We'll use codeop.compile_command to check this with the real parser
668 # We'll use codeop.compile_command to check this with the real parser
@@ -653,12 +677,13 b' class TransformerManager:'
653 if res is None:
677 if res is None:
654 return 'incomplete', find_last_indent(lines)
678 return 'incomplete', find_last_indent(lines)
655
679
656 if toks_last_line[-2].type in {tokenize.NEWLINE, tokenize.NL}:
680 if last_line_token[-1].type == tokenize.DEDENT:
657 return 'complete', None
681 if ends_with_newline:
682 return 'complete', None
683 return 'incomplete', find_last_indent(lines)
658
684
659 if toks_last_line[-2].type == tokenize.DEDENT:
685 if len(last_line_token) <= 1:
660 if not lines[-1].endswith('\n'):
686 return 'incomplete', find_last_indent(lines)
661 return 'incomplete', find_last_indent(lines)
662
687
663 return 'complete', None
688 return 'complete', None
664
689
General Comments 0
You need to be logged in to leave comments. Login now