IPython扩展中的多线变压器问题

IPython扩展中的多线变压器问题,ipython,tokenize,multiline,Ipython,Tokenize,Multiline,我试图在IPython扩展模块中使用TokenInputTransformer,但使用多行输入的token Transformer的标准实现似乎有问题。考虑下面的最小扩展: from IPython.core.inputtransformer import TokenInputTransformer @TokenInputTransformer.wrap def test_transformer(tokens): return tokens def load_ipython_exte

我试图在IPython扩展模块中使用
TokenInputTransformer
,但使用多行输入的token Transformer的标准实现似乎有问题。考虑下面的最小扩展:

from IPython.core.inputtransformer import TokenInputTransformer

@TokenInputTransformer.wrap
def test_transformer(tokens):
    return tokens

def load_ipython_extension(ip):
    for s in (ip.input_splitter, ip.input_transformer_manager): 
        s.python_line_transforms.extend([test_transformer()])
    print "Test activated"
在IPython 1.1.0中加载扩展时,我得到一个未处理的多行输入异常:

In [1]: %load_ext test
Test activated

In [2]: abs(
   ...: 2
   ...: )
Traceback (most recent call last):
  File "/Applications/anaconda/bin/ipython", line 6, in <module>
    sys.exit(start_ipython())
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/__init__.py", line 118, in start_ipython
    return launch_new_instance(argv=argv, **kwargs)
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/config/application.py", line 545, in launch_instance
    app.start()
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/terminal/ipapp.py", line 362, in start
    self.shell.mainloop()
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/terminal/interactiveshell.py", line 436, in mainloop
    self.interact(display_banner=display_banner)
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/terminal/interactiveshell.py", line 548, in interact
    self.input_splitter.push(line)
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/core/inputsplitter.py", line 620, in push
    out = self.push_line(line)
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/core/inputsplitter.py", line 655, in push_line
    line = transformer.push(line)
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/core/inputtransformer.py", line 152, in push
    return self.output(tokens)
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/core/inputtransformer.py", line 157, in output
    return untokenize(self.func(tokens)).rstrip('\n')
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/utils/_tokenize_py2.py", line 276, in untokenize
    return ut.untokenize(iterable)
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/utils/_tokenize_py2.py", line 214, in untokenize
    self.add_whitespace(start)
  File "/Applications/anaconda/lib/python2.7/site-packages/IPython/utils/_tokenize_py2.py", line 199, in add_whitespace
    assert row >= self.prev_row
AssertionError

If you suspect this is an IPython bug, please report it at:
    https://github.com/ipython/ipython/issues
or send an email to the mailing list at ipython-dev@scipy.org

You can print a more detailed traceback right now with "%tb", or use "%debug"
to interactively debug it.

Extra-detailed tracebacks for bug-reporting purposes can be enabled via:
    %config Application.verbose_crash=True
[1]中的
:%load\u ext test
测试激活
在[2]中:abs(
...: 2
...: )
回溯(最近一次呼叫最后一次):
文件“/Applications/anaconda/bin/ipython”,第6行,在
sys.exit(start_ipython())
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/_init__.py”,第118行,在start_IPython中
返回启动新实例(argv=argv,**kwargs)
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/config/application.py”,第545行,在launch_实例中
app.start()
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/terminal/ipapp.py”,第362行,开头
self.shell.mainloop()
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/terminal/interactiveshell.py”,第436行,在mainloop中
self.interactive(display\u banner=display\u banner)
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/terminal/interactiveshell.py”,第548行,在interact中
自输入拆分器推送(行)
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/core/inputsplitter.py”,第620行,在push中
out=自推线(线)
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/core/inputsplitter.py”,第655行,在push_行中
线路=变压器。推动(线路)
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/core/inputtransformer.py”,第152行,在push中
返回self.output(令牌)
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/core/inputtransformer.py”,第157行,在输出中
返回untokenize(self.func(令牌)).rstrip('\n')
untokenize中的文件“/Applications/anaconda/lib/python2.7/site packages/IPython/utils/_-tokenize_-py2.py”,第276行
返回ut.untokenize(iterable)
untokenize中的文件“/Applications/anaconda/lib/python2.7/site packages/IPython/utils/_-tokenize_-py2.py”,第214行
self.add_空格(开始)
文件“/Applications/anaconda/lib/python2.7/site packages/IPython/utils/_-tokenize_-py2.py”,第199行,添加空白
断言行>=self.prev\u行
断言错误
如果您怀疑这是IPython错误,请在以下地址报告:
https://github.com/ipython/ipython/issues
或者向ipython的邮件列表发送电子邮件-dev@scipy.org
您可以立即使用“%tb”打印更详细的回溯,或使用“%debug”
以交互方式调试它。
可通过以下方式启用用于错误报告目的的额外详细回溯:
%config Application.verbose\u crash=True

我是做错了什么,还是真的是IPython bug?

我想这真的是IPython bug。具体地说,当涉及方括号(
()[]{}
)的表达式分布在多行上时,我们处理标记化的方法会失败。我正试图找出我们能做些什么。

回答得有点晚,但是,我试图在我自己的扩展中使用它,只是遇到了同样的问题。我通过简单地从列表中删除NL解决了这个问题(它与end语句中的换行标记不同),NL标记只出现在[]、()、{}内,所以它应该可以安全地删除

from tokenize import NL
@TokenInputTransformer.wrap
def mat_transformer(tokens):
    tokens = list(filter(lambda t: t.type != NL, tokens)) 
    return tokens

如果您正在寻找完整的示例,我已经在那里发布了我的愚蠢代码:

谢谢您的快速回复!我想我可以通过直接从线路变压器(例如
@statelementInputTransformer
)调用tokenize.generate_令牌,执行所有令牌操作,然后调用tokenize.untokenize来绕过这个问题。然而,这可能是浪费时间,而且显然不是很优雅……是的,你应该可以做你正在做的事情,但我想你是第一个尝试的人。
TokenInputTransformer
包装器需要做更多的工作。@ThomasK嗨,我遇到了类似的难题,最终删除了NL标记,这样它就停止了崩溃,并且还没有找到一个不起作用的情况。我实际上不得不修改过滤器,因为标记=列表(过滤器(lambda t:t[0]!=NL,标记))我不知道这是否与我正在使用的ipython/python版本有关,或者与修改令牌列表的代码的其他部分有关…@marclombardi这与ipyhon有关,我不认为人们可能会使用这个功能,它相当复杂。我同意,可能只有少数人使用这个功能,这也解释了为什么它还没有在ipython得到修复。无论如何,您的解决方案非常有效,非常感谢!