debugging Python breakpoint()自动读取所有STDIN --如何禁用它?

wlsrxk51  于 2023-06-23  发布在  Python
关注(0)|答案(1)|浏览(106)

下面是一个Python脚本示例。

import sys
print("Hello, world!")
for i, line in enumerate(sys.stdin):
    print(line)
    print(f"Before breakpoint: {i}")
    breakpoint()
    print(f"After breakpoint: {i}")

运行seq 1 10 | python tmp.py将在指定的断点处启动调试器,但是它会自动读取所有标准输入。

seq 1 10 | python tmp.py 
Hello, world!
1

Before breakpoint: 0
> .../tmp.py(9)<module>()
-> print(f"After breakpoint: {i}")
(Pdb) 2
(Pdb) 3
(Pdb) 4
(Pdb) 5
(Pdb) 6
(Pdb) 7
(Pdb) 8
(Pdb) 9
(Pdb) 10
(Pdb) 
Traceback (most recent call last):
  File ".../tmp.py", line 9, in <module>
    print(f"After breakpoint: {i}")
  File ".../tmp.py", line 9, in <module>
    print(f"After breakpoint: {i}")
  File ".../python3.10/bdb.py", line 90, in trace_dispatch
    return self.dispatch_line(frame)
  File ".../python3.10/bdb.py", line 115, in dispatch_line
    if self.quitting: raise BdbQuit
bdb.BdbQuit

如何阻止breakpoint()阅读STDIN?也就是说,我仍然需要breakpoint(),但不希望它自动消耗和执行STDIN。我查看了文档[1],它没有提到这个STDIN行为,也没有禁用它的选项。
[1]我https://docs.python.org/3.10/library/functions.html?highlight=breakpoint#breakpoint在Ubuntu 20.04.6 LTS(WSL)上使用Python 3.10.9

gt0wga4j

gt0wga4j1#

回答我自己的问题。感谢评论,并感谢this answer [1],这里有一个有效的解决方案。
诀窍是将TTY作为PDB的STDIN/OUT/ERR附加,同时保持STDIN/OUT/ERR不变。

import sys

print("Hello, world!")

def tty_pdb():
    from contextlib import (_RedirectStream,
                            redirect_stdout, redirect_stderr)
    class redirect_stdin(_RedirectStream):
        _stream = 'stdin'
    with open('/dev/tty', 'r') as new_stdin, \
         open('/dev/tty', 'w') as new_stdout, \
         open('/dev/tty', 'w') as new_stderr, \
         redirect_stdin(new_stdin), \
         redirect_stdout(new_stdout), redirect_stderr(new_stderr):
        __import__('pdb').set_trace()

for i, line in enumerate(sys.stdin):
    print(line)
    print(f"Before breakpoint: {i}")
    tty_pdb()
    print(f"After breakpoint: {i}")

它很优雅--不需要调整调用python程序的脚本!感谢[1]的作者(我已经投了他们的赞成票)。
[1]- https://stackoverflow.com/a/48430325/1506477

相关问题