【问题标题】:Python3.0 - tokenize and untokenizePython3.0 - 标记化和取消标记化
【发布时间】:2010-10-30 09:32:59
【问题描述】:

我正在使用类似于以下简化脚本的东西从较大的文件中解析 python 的 sn-ps:

import io
import tokenize

src = 'foo="bar"'
src = bytes(src.encode())
src = io.BytesIO(src)

src = list(tokenize.tokenize(src.readline))

for tok in src:
  print(tok)

src = tokenize.untokenize(src)

虽然python2.x中的代码不一样,但它使用相同的习语并且工作得很好。但是,使用 python3.0 运行上面的 sn-p,我得到了这个输出:

(57, 'utf-8', (0, 0), (0, 0), '')
(1, 'foo', (1, 0), (1, 3), 'foo="bar"')
(53, '=', (1, 3), (1, 4), 'foo="bar"')
(3, '"bar"', (1, 4), (1, 9), 'foo="bar"')
(0, '', (2, 0), (2, 0), '')

Traceback (most recent call last):
  File "q.py", line 13, in <module>
    src = tokenize.untokenize(src)
  File "/usr/local/lib/python3.0/tokenize.py", line 236, in untokenize
    out = ut.untokenize(iterable)
  File "/usr/local/lib/python3.0/tokenize.py", line 165, in untokenize
    self.add_whitespace(start)
  File "/usr/local/lib/python3.0/tokenize.py", line 151, in add_whitespace
    assert row <= self.prev_row
AssertionError

我已搜索此错误及其原因的引用,但找不到任何内容。我做错了什么,我该如何纠正?

[编辑]

partisann 观察到在源代码中添加换行符会导致错误消失后,我开始弄乱我正在取消标记的列表。似乎 EOF 令牌如果没有紧跟在换行符之前会导致错误,因此删除它可以消除错误。以下脚本运行没有错误:

import io
import tokenize

src = 'foo="bar"'
src = bytes(src.encode())
src = io.BytesIO(src)

src = list(tokenize.tokenize(src.readline))

for tok in src:
  print(tok)

src = tokenize.untokenize(src[:-1])

【问题讨论】:

    标签: python python-3.x tokenize lexical-analysis


    【解决方案1】:

    如果将 untokenize 的输入限制为令牌的前 2 项,它似乎可以工作。

    import io
    import tokenize
    
    src = 'foo="bar"'
    src = bytes(src.encode())
    src = io.BytesIO(src)
    
    src = list(tokenize.tokenize(src.readline))
    
    for tok in src:
      print(tok)
    
    src = [t[:2] for t in src]
    src = tokenize.untokenize(src)
    

    【讨论】:

      【解决方案2】:

      src = 'foo="bar"\n'
      你忘记换行了。

      【讨论】:

      • 不错!你知道这是为什么吗?似乎它应该以任何一种方式工作,至少在 python2.x 中是这样。
      • 我不明白这有什么关系?
      • 似乎您应该针对 Python 提交错误。换行符似乎没有必要。
      • 它看起来确实像一个错误。 Tbh,我只是猜到了,因为这是 C 编译器很常见的错误。
      猜你喜欢
      • 1970-01-01
      • 2016-10-30
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      相关资源
      最近更新 更多