Skip to content

Instantly share code, notes, and snippets.

@GaretJax
Created March 12, 2011 14:57
Show Gist options
  • Select an option

  • Save GaretJax/867293 to your computer and use it in GitHub Desktop.

Select an option

Save GaretJax/867293 to your computer and use it in GitHub Desktop.
A simple context manager to redirect output written to given file object to another one or to discard the data entirely.
import os
class _FileRedirect(object):
"""
A simple context manager to redirect output written to given file object
to another one or to discard the data entirely.
It works at OS level to allow to redirect/discard output from libraries
written in C too. This means that only file-like objects working on real
file descriptors are supported (sys.stdout, sys.stderr or any file opened
using the ``open`` or ``os.fdopen`` functions).
"""
def __init__(self, f, to=None):
"""
Omitting the ``to`` argument causes the output to be discarded
"""
self.f = f
self.to = to
self.fd = f.fileno()
def __enter__(self):
self.f.flush()
self.old = os.dup(self.fd)
if self.to is None:
os.close(self.fd)
os.open(os.devnull, os.O_CREAT|os.O_WRONLY) == self.fd
else:
os.dup2(self.to.fileno(), self.fd)
def __exit__(self, type, value, traceback):
self.f.flush()
if self.to is not None:
self.to.flush()
os.dup2(self.old, self.fd)
os.close(self.old)
def discard(fh):
"""
Functional wrapper around the ``_FileRedirect`` context manager to discard
data printed to the given file object.
"""
return _FileRedirect(fh, None)
def redirect(from_fh, to_fh):
"""
Functional wrapper around the ``_FileRedirect`` context manager to redirect
data written to a file to another one.
"""
return _FileRedirect(from_fh, to_fh)
# Use it like this:
import sys
def verbose():
print "Hello world\n" * 100
with discard(sys.stdout):
verbose()
# or:
def not_an_error():
print >>sys.stderr, "Hello world"
with redirect(sys.stderr, sys.stdout):
not_an_error()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment