##// END OF EJS Templates
Switch inputtransformer2 back to stdlib tokenize module
Thomas Kluyver -
Show More
@@ -9,9 +9,8 b' This includes the machinery to recognise and transform ``%magic`` commands,'
9 9
10 10 from codeop import compile_command
11 11 import re
12 import tokenize
12 13 from typing import List, Tuple
13 from IPython.utils import tokenize2
14 from IPython.utils.tokenutil import generate_tokens
15 14
16 15 _indent_re = re.compile(r'^[ \t]+')
17 16
@@ -140,7 +139,7 b' class MagicAssign(TokenTransformBase):'
140 139 if (assign_ix is not None) \
141 140 and (len(line) >= assign_ix + 2) \
142 141 and (line[assign_ix+1].string == '%') \
143 and (line[assign_ix+2].type == tokenize2.NAME):
142 and (line[assign_ix+2].type == tokenize.NAME):
144 143 return cls(line[assign_ix+1].start)
145 144
146 145 def transform(self, lines: List[str]):
@@ -172,10 +171,10 b' class SystemAssign(TokenTransformBase):'
172 171 assign_ix = _find_assign_op(line)
173 172 if (assign_ix is not None) \
174 173 and (len(line) >= assign_ix + 2) \
175 and (line[assign_ix + 1].type == tokenize2.ERRORTOKEN):
174 and (line[assign_ix + 1].type == tokenize.ERRORTOKEN):
176 175 ix = assign_ix + 1
177 176
178 while ix < len(line) and line[ix].type == tokenize2.ERRORTOKEN:
177 while ix < len(line) and line[ix].type == tokenize.ERRORTOKEN:
179 178 if line[ix].string == '!':
180 179 return cls(line[ix].start)
181 180 elif not line[ix].string.isspace():
@@ -289,7 +288,7 b' class EscapedCommand(TokenTransformBase):'
289 288 """
290 289 for line in tokens_by_line:
291 290 ix = 0
292 while line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
291 while line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
293 292 ix += 1
294 293 if line[ix].string in ESCAPE_SINGLES:
295 294 return cls(line[ix].start)
@@ -338,7 +337,7 b' class HelpEnd(TokenTransformBase):'
338 337 if len(line) > 2 and line[-2].string == '?':
339 338 # Find the first token that's not INDENT/DEDENT
340 339 ix = 0
341 while line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
340 while line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
342 341 ix += 1
343 342 return cls(line[ix].start, line[-2].start)
344 343
@@ -365,11 +364,31 b' class HelpEnd(TokenTransformBase):'
365 364 return lines_before + [new_line] + lines_after
366 365
367 366 def make_tokens_by_line(lines):
367 """Tokenize a series of lines and group tokens by line.
368
369 The tokens for a multiline Python string or expression are
370 grouped as one line.
371 """
372 # NL tokens are used inside multiline expressions, but also after blank
373 # lines or comments. This is intentional - see https://bugs.python.org/issue17061
374 # We want to group the former case together but split the latter, so we
375 # track parentheses level, similar to the internals of tokenize.
376 NEWLINE, NL = tokenize.NEWLINE, tokenize.NL
368 377 tokens_by_line = [[]]
369 for token in generate_tokens(iter(lines).__next__):
378 parenlev = 0
379 try:
380 for token in tokenize.generate_tokens(iter(lines).__next__):
370 381 tokens_by_line[-1].append(token)
371 if token.type == tokenize2.NEWLINE:
382 if (token.type == NEWLINE) \
383 or ((token.type == NL) and (parenlev <= 0)):
372 384 tokens_by_line.append([])
385 elif token.string in {'(', '[', '{'}:
386 parenlev += 1
387 elif token.string in {')', ']', '}'}:
388 parenlev -= 1
389 except tokenize.TokenError:
390 # Input ended in a multiline string or expression. That's OK for us.
391 pass
373 392
374 393 return tokens_by_line
375 394
@@ -490,21 +509,21 b' class TransformerManager:'
490 509 return 'invalid', None
491 510
492 511 tokens_by_line = make_tokens_by_line(lines)
493 if tokens_by_line[-1][-1].type != tokenize2.ENDMARKER:
512 if tokens_by_line[-1][-1].type != tokenize.ENDMARKER:
494 513 # We're in a multiline string or expression
495 514 return 'incomplete', find_last_indent(lines)
496 515
497 516 # Find the last token on the previous line that's not NEWLINE or COMMENT
498 517 toks_last_line = tokens_by_line[-2]
499 518 ix = len(toks_last_line) - 1
500 while ix >= 0 and toks_last_line[ix].type in {tokenize2.NEWLINE,
501 tokenize2.COMMENT}:
519 while ix >= 0 and toks_last_line[ix].type in {tokenize.NEWLINE,
520 tokenize.COMMENT}:
502 521 ix -= 1
503 522
504 523 if toks_last_line[ix].string == ':':
505 524 # The last line starts a block (e.g. 'if foo:')
506 525 ix = 0
507 while toks_last_line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
526 while toks_last_line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
508 527 ix += 1
509 528 indent = toks_last_line[ix].start[1]
510 529 return 'incomplete', indent + 4
General Comments 0
You need to be logged in to leave comments. Login now