python诅咒中的堆栈溢出。它是模块中的错误吗?

时间:2015-02-01 15:28:14

标签: python curses

我只是初学者使用' curses'并且不能肯定地说它是否是蟒蛇诅咒中的一个错误'模块或我的错误用法。

我有以下测试代码:

import curses
import curses.textpad

screen = curses.initscr()
curses.noecho()
cl = curses.newwin( 15, 80, 10, 1 )
txtbox = curses.textpad.Textbox(cl,insert_mode=True)

def main( scr ):
    global txtbox
    s = txtbox.edit()
    print(s)    

if __name__ == '__main__':
    ret = curses.wrapper( main )

当我运行它时,它启动正常,但是当按下任何键时,它会启动无限递归并导致堆栈溢出。从curses/textpad.py代码中可以看出,处理键事件的函数实际上是自称:

def _insert_printable_char(self, ch):
    (y, x) = self.win.getyx()
    if y < self.maxy or x < self.maxx:
        if self.insert_mode:
            oldch = self.win.inch()

        try:
            self.win.addch(ch)
        except curses.error:
            pass
        if self.insert_mode:
            (backy, backx) = self.win.getyx()
            if curses.ascii.isprint(oldch):
                self._insert_printable_char(oldch) # <--- Is it bug?
                self.win.move(backy, backx)

它是python的textpad.py模块中的错误,还是一些诅咒&#39;我的代码中错过了初始化步骤?

1 个答案:

答案 0 :(得分:1)

我可以重现这个问题,它似乎是通过使文本框下面的窗口触发而引发的,并且#34;太宽了#34;在插入模式下。避免多次初始化(包装器完成所有操作),请考虑:

import curses
import curses.textpad
import curses.wrapper

def main(scr):
    win = curses.newwin( 15, 60, 10, 1 )
    txtbox = curses.textpad.Textbox(win, insert_mode=True)
    s = txtbox.edit()
    return s

if __name__ == '__main__':
    ret = curses.wrapper( main )
    print ret

但是如果你将第二个arg更改为newwin回到80,那么bug就会触发。 (_insert_printable_char中用于实现插入模式的递归似乎很好 - 它应该终止,因为它最终遇到边框或不可打印的字符,但显然它不是在窗口是太宽泛了。)

我会继续调试,添加日志记录以确切了解出现了什么问题,但同时我想发布此信息,因为您可以使用稍微窄一点的窗口来避免触发错误)。