After replacing sys.stdout
with a Tee logger (to redirect output to a file), PDB no longer works properly. For example, pressing the up arrow produces ^[[A
instead of the previous command.
The problem can be reproduced using this snippet:
import sys
import pdb
class Tee(object):
def __init__(self, name, mode):
self.file = open(name, mode)
self.stdout = sys.stdout
sys.stdout = self
def __del__(self):
sys.stdout = self.stdout
self.file.close()
def write(self, data):
self.file.write(data)
self.stdout.write(data)
def flush(self):
self.file.flush()
sys.stdout = Tee('test.txt', 'w')
pdb.set_trace()
Is there any way to replace sys.stdout
without breaking PDB?
(1) You cannot have interactivity on the tee'd output because it's a regular stream, and not a terminal. A terminal allows to do a ton of things: position the cursor, erase contents, read keys, echo keypresses to the screen, etc. A regular file on a disk can't do all these things, this is why pdb
fails to do these things in interactive mode. You can check that sys.stdout.isatty()
returns True
is you run a REPL.
(2) You can of course change every print
function invocation in your code to write to stdout and to whatever file you want, because you can redefine print
. This works in Python 3, and in Python 2.7 if you from __future__ import print
. Then you can do things like this:
system_print = print # preserve the original.
def print_also_to(other_file):
def tee_print(*args, **kwargs):
system_print(*args, **kwargs) # Normally prints to stdout.
system_print(*args, **kwargs, file=other_file) # Write a copy.
return tee_print
print = print_also_to(open('/tmp/copy-of-stdout')) # A crude example.
print("Hello world!") # Unmodified code.
With print
statements , your situation is worse. Use strace
on Linux or DTrace
on macOS to capture the writing to stdout (and elsewhere) and redirect it to a file when starting your process:
strace -e trace=write -o writes.txt python your-script.py
It will write to the file something like write(1, 'Hello world!')
. You would need to parse it and reconstruct output to stdout (1) specifically to produce a real copy of the output.
I suppose pdb
's interactive mode will work under this, too; at the very least, Python REPL works fine under strace.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.