处理 python pdb flakiness re/stdout 的最佳方法?

发布于 2024-08-16 09:13:42 字数 152 浏览 3 评论 0原文

如果我有一个 stdout 被重定向的程序,我的 pdb 会提示所有内容都转到重定向,因为该库被编写为写入 stdout。

通常这个问题很微妙,让我认为程序在真正等待输入时挂起。

人们如何解决这个问题? (不幸的是,不能使用其他调试器,例如 winpdb)。

If I have a program where stdout is redirected, my pdb prompts all go to the redirection, because the library was written to write to stdout.

Oftentimes this problem is subtle, causing me to think a program is hanging when it's really waiting for input.

How do people work around this? (Unfortunately, using other debuggers like winpdb is not an option).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

枯叶蝶 2024-08-23 09:13:42

这个答案只是为了补充 Ned 的答案,作为一种包装 pdb.py main() 函数的方式,不需要复制 40 行只是为了更改其中一行:

# sane_pdb.py: launch Pdb with stdout on original
import sys, pdb
def fixed_pdb(Pdb=pdb.Pdb):
    '''make Pdb() tied to original stdout'''
    return Pdb(stdout=sys.__stdout__)

if __name__ == '__main__':
    pdb.Pdb = fixed_pdb
    pdb.main()

我不知道它是否真的适用于提问者的问题,但它确实按照内德所描述的那样......

This answer is just to supplement Ned's, as a way of wrapping the pdb.py main() function in a manner which doesn't require copying 40 lines just to change one of them:

# sane_pdb.py: launch Pdb with stdout on original
import sys, pdb
def fixed_pdb(Pdb=pdb.Pdb):
    '''make Pdb() tied to original stdout'''
    return Pdb(stdout=sys.__stdout__)

if __name__ == '__main__':
    pdb.Pdb = fixed_pdb
    pdb.main()

I don't know if it actually works for the questioner's problem, but it does what Ned described...

绝不服输 2024-08-23 09:13:42

这里的问题是 PDB 默认使用 Cmd 类:

use_rawinput = 1

这意味着 Cmd 默认情况下将使用 raw_input() 方法而不是 sys.stdout.readline() 来读取从控制台。这样做是因为 raw_input() 支持历史记录(仅当加载 readline 模块时)和其他有用的位。唯一的问题是 raw_input() 不支持重定向,因此如果您有一个脚本:

#!/usr/bin/python
name=raw_input("Enter your name: ")

并运行它

> python test.py
Enter your name: Alex

,但是,如果您使用输出重定向运行它,它将卡住,

> python test.py | tee log

这正是 PDB 使用的内容以及原因它也被卡住了。正如我提到的,sys.stdin.readline() 支持重定向,如果您使用 readline() 重写上述脚本,它应该可以工作。

回到最初的问题,您所需要做的就是告诉 Cmd 不要使用 raw_input()

Cmd.use_rawinput = 0

或者

pdb = pdb.Pdb()
pdb.use_rawinput=0
pdb.set_trace()

The problem here is that PDB uses Cmd class where by default:

use_rawinput = 1

It means that Cmd will use raw_input() method by default instead of sys.stdout.readline() to read from the console . This is done because raw_input() supports history (only if readline module is loaded) and other useful bits . The only issue is that raw_input() does not support redirection, so if you have a script:

#!/usr/bin/python
name=raw_input("Enter your name: ")

and run it

> python test.py
Enter your name: Alex

but, if you run it with output redirection it will stuck

> python test.py | tee log

this is exactly what PDB uses and why it's stuck as well. As I mentioned sys.stdin.readline() supports redirection and if you rewrite the above script using readline() it should work.

Back to the original issue all you need to do is to tell Cmd to not use raw_input():

Cmd.use_rawinput = 0

or

pdb = pdb.Pdb()
pdb.use_rawinput=0
pdb.set_trace()
朮生 2024-08-23 09:13:42

如果您在代码中调用 pdb,则可以将自己的 stdout 传递到构造函数中。 sys.__stdout__ 可能是一个不错的选择。

如果您从命令行调用 pdb,则可以将 pdb.py 中的 main() 函数复制到您自己的 sane_pdb.py 中。然后将 Pdb() 初始化更改为:

pdb = Pdb(stdout=sys.__stdout__)

然后您可以调用 sane_pdb.py 而不是 pdb.py。您必须将 40 行复制到您自己的文件中才能更改其中一行,这并不令人惊奇,但这是一种选择。

If you are invoking pdb in code, you can pass your own stdout into the constructor. sys.__stdout__ might be a good choice.

If you are invoking pdb from the command line, you could copy the main() function from pdb.py into your own sane_pdb.py. Then change the Pdb() initialization to:

pdb = Pdb(stdout=sys.__stdout__)

Then you can invoke sane_pdb.py instead of pdb.py. It's not awesome that you'd have to copy 40 lines into your own file just to change one of them, but it's an option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文