С чего бы это
if 1 \
and 0:
pass
простейший из кодовых ударов в цикле токенизации / untokenize
import tokenize
import cStringIO
def tok_untok(src):
f = cStringIO.StringIO(src)
return tokenize.untokenize(tokenize.generate_tokens(f.readline))
src='''if 1 \\
and 0:
pass
'''
print tok_untok(src)
Бросает:
AssertionError:
File "/mnt/home/anushri/untitled-1.py", line 13, in <module>
print tok_untok(src)
File "/mnt/home/anushri/untitled-1.py", line 6, in tok_untok
tokenize.untokenize(tokenize.generate_tokens(f.readline))
File "/usr/lib/python2.6/tokenize.py", line 262, in untokenize
return ut.untokenize(iterable)
File "/usr/lib/python2.6/tokenize.py", line 198, in untokenize
self.add_whitespace(start)
File "/usr/lib/python2.6/tokenize.py", line 187, in add_whitespace
assert row <= self.prev_row
Есть ли обходной путь без изменения src для токенизации (кажется, \
виновник)
Другой пример, где это терпит неудачу, - если нет новой строки в конце, например src='if 1:pass'
терпит неудачу с той же ошибкой
Обход:
Но, похоже, использование untokenize по-другому работает
def tok_untok(src):
f = cStringIO.StringIO(src)
tokens = [ t[:2] for t in tokenize.generate_tokens(f.readline)]
return tokenize.untokenize(tokens)
т.е. не передавать обратно весь кортеж токена, а только t [: 2]
хотя python doc говорит, что дополнительные аргументы пропущены
Преобразует токены обратно в исходный код Python. Итерируемый должен вернуть
последовательности по крайней мере с двумя элементами,
тип токена и строка токена.
Любые дополнительные элементы последовательности
игнорироваться.