Source code for bronx.system.unistd

"""
Utilities to work on file descriptors through the standard Linux C layer.

The name of this module is directly inspired from the eponym C library.
"""
from contextlib import contextmanager
import os
import sys

#: No automatic export
__all__ = []


[docs]@contextmanager def stdout_redirected(to=os.devnull): """ Redirect *sys.stdout* to **to**. Usage:: with stdout_redirected(to=filename): print("from Python") import os os.system("echo non-Python applications are also supported") """ return redirected_stdio(module=sys, stdio='stdout', to=to)
[docs]@contextmanager def stderr_redirected(to=os.devnull): """ Redirect *sys.stderr* to **to**. Usage:: with stdout_redirected(to=filename): # there, an error message won't be printed """ return redirected_stdio(module=sys, stdio='stderr', to=to)
[docs]def redirected_stdio(module=sys, stdio='stdout', to=os.devnull): """ Redirect **module.stdio** to **to**, e.g. (default): *sys.stdout* to *os.devnull* Usage:: with redirected_stdio(sys, out='stdout', to=filename): print("from Python") import os os.system("echo non-Python applications are also supported") Warning: Use with care. It will crash if **module.stdio** is already redirected to a File like object that is not a "real" physical file (e.g. a StringIO object). Because of that, it can not be tested with the unitest module since usual test runner redirect stdout/stderr to memory. Inspired from: http://stackoverflow.com/questions/5081657/how-do-i-prevent-a-c-shared-library-to-print-on-stdout-in-python """ fd = getattr(module, stdio).fileno() def _redirect_stdout(to): getattr(module, stdio).close() # + implicit flush() os.dup2(to.fileno(), fd) # fd writes to 'to' file setattr(module, stdio, os.fdopen(fd, 'w')) # Python writes to fd with os.fdopen(os.dup(fd), 'w') as old_stdio: with open(to, 'w') as f: _redirect_stdout(f) try: yield # allow code to be run with the redirected stdio finally: _redirect_stdout(to=old_stdio) # restore stdio.