Intercepting Assignments To Sys.stdout And Sys.stderr
The sys module has a couple of global properties that I'm interested in: sys.stdout and sys.stderr. I'm building a module of my own, that (among other things), replaces sys.stdout
Solution 1:
The only real way to completely override stdout on python is to actually override the stdout file descriptor (1). This can be done using the dup2
syscall.
Below is a cross-platform example showing how to override stdout, allowing to use custom logic on all data written to it. In this example, the logic just duplicates all characters written to stdout.
import os
import sys
import threading
defhandle_stdout(fake_stdout, real_stdout):
whilenot fake_stdout.closed andnot real_stdout.closed:
char = fake_stdout.read(1)
real_stdout.write(char * 2)
defoverride_stdout():
stdout_fd = 1
pipe_reader_fd, pipe_writer_fd = os.pipe()
pipe_reader = os.fdopen(pipe_reader_fd, 'r')
original_stdout_writer = os.fdopen(os.dup(stdout_fd), 'w')
os.dup2(pipe_writer_fd, stdout_fd)
return pipe_reader, original_stdout_writer
# Override stdout
pipe_reader, original_stdout_writer = override_stdout()
thread = threading.Thread(target=handle_stdout, args=(pipe_reader, original_stdout_writer))
thread.start()
# Write stuff to stdoutprint('foobar')
# Cleanup to allow background thread to shut down
pipe_reader.close()
original_stdout_writer.close()
Running this example will output:
ffoooobbaarr
For some versions of python, you'll have to set the PYTHONLEGACYWINDOWSSTDIO
environment variable to a non-empty string to make this example to work on windows.
Post a Comment for "Intercepting Assignments To Sys.stdout And Sys.stderr"