There is a function named redirect which temporarily redirects operations on file source
to file target
.
def redirect(source, target):
source.flush()
fd = source.fileno()
with os.fdopen(os.dup(fd), source.mode) as source2:
os.dup2(target.fileno(), fd)
try:
yield
finally:
source.flush()
os.dup2(source2.fileno(), fd)
It was being called from the same module as
with tempfile.TemporaryFile() as tmp:
with redirect(sys.stdout, tmp), nogil:
Upon compiling, it used to generate an AttributeError
AttributeError: StringIO instance has no attribute 'fileno'
at the line fd = source.fileno()
.
But when I replaced sys.stdout
with sys.__stdout__
, there was no such error, and the tests passed successfully.
Now I'm really puzzled, why __stdout__
worked but not stdout
.
As Greg mentioned in the comments, that wouldn't work. What I normally do is temporarily change my stdout.
And use that context manager with :
This usages doesn't care whether the initial stdout has a FD or not.