Python tokenize中的bug?
为什么这段
if 1 \
and 0:
pass
最简单的代码在进行分词和还原词时会出错呢?
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='if 1:pass'
也会出现同样的错误
解决办法:
但似乎用另一种方式进行还原词是可行的
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文档说额外的参数会被忽略
将词元转换回Python源代码。可迭代对象必须返回至少包含两个元素的序列,分别是词元类型和词元字符串。任何额外的序列元素都会被忽略。