包装标准/标准输出会导致 IPython 失去自动完成和历史记录功能



我正在开发一个使用IPython嵌入式外壳功能的脚本,作为要求,它必须将stdin/stdout中的所有数据记录到一个文件中。出于这个原因,我决定为他们编写包装器;但是,在切换流后,我的嵌入式 IPython shell 失去了其自动完成和历史记录功能,当我按下箭头按钮时会输出如下内容:

In [1]: ^[[A^[[B^[[A^[[C...

我猜包装器以某种方式阻止了 IPython 识别用于向上、向下、向左和向右箭头(ESC[#AESC[#BESC[#CESC[#D)的 ANSI 转义序列。

这是演示我的问题的代码:

import sys
from time import strftime
import IPython
# Custom IO class for file logging
class StdinLogger (object):
    def __init__(self, wrapped, file):
        # double-underscore everything to prevent clashes with names of
        # attributes on the wrapped stream object.
        self.__wrapped = wrapped
        self.__file = file
    def __getattr__(self, name):
        return getattr(self.__wrapped, name)
    def readline(self):
        str = self.__wrapped.readline()
        self.__file.write(str)
        self.__file.flush()
        return str

# Custom IO class for file logging
class StdoutLogger (object):
    def __init__(self, wrapped, file):
        # double-underscore everything to prevent clashes with names of
        # attributes on the wrapped stream object.
        self.__wrapped = wrapped
        self.__file = file
    def __getattr__(self, item):
        return getattr(self.__wrapped, item)
    def write(self, str):
        self.__file.write(str)
        self.__file.flush()
        self.__wrapped.write(str)
        self.__wrapped.flush()

f = open("LOG-" + strftime("%Y-%m-%d-%H-%M-%S") + ".txt", 'w')
# Initialize the file logger
sys.stdin = StdinLogger(sys.stdin, f)
sys.stdout = StdoutLogger(sys.stdout, f)

# Embed IPython shell
IPython.embed(banner1="", banner2="")

关于如何解决这个问题的任何想法?

提前谢谢。

@Carreau(IPython 核心开发人员)在 Github 上对此问题的回应:

问题是,特别是使用提示工具包标准输出会更多 而不是流,因为您实际上是在屏幕上绘制/擦除/重绘,并且 由于它使用事件循环和异步完成,因此不能考虑 stdin/out/err 足以知道当前状态。

所以你(可能)需要挂接到prompt_toolkit和 覆盖 VT100 输入/输出和/或窗口输入/输出。

我们很可能需要额外的钩子来在 IPython 中设置它 启动。

最新更新