Created
March 12, 2011 14:57
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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