Search code examples
pythonhttp-redirectstdoutstderr

Temporarily Redirect stdout/stderr


Is it possible to temporarily redirect stdout/stderr in Python (i.e. for the duration of a method)?

Edit:

The problem with the current solutions (which I at first remembered but then forgot) is that they don't redirect; rather, they just replace the streams in their entirety. Hence, if a method has a local copy of one the variable for any reason (e.g. because the stream was passed as a parameter to something), it won't work.

Any solutions?


Solution

  • To solve the issue that some function might have cached sys.stdout stream as a local variable and therefore replacing the global sys.stdout won't work inside that function, you could redirect at a file descriptor level (sys.stdout.fileno()) e.g.:

    from __future__ import print_function
    import os
    import sys
    
    def some_function_with_cached_sys_stdout(stdout=sys.stdout):
        print('cached stdout', file=stdout)
    
    with stdout_redirected(to=os.devnull), merged_stderr_stdout():
        print('stdout goes to devnull')
        some_function_with_cached_sys_stdout()
        print('stderr also goes to stdout that goes to devnull', file=sys.stderr)
    print('stdout is back')
    some_function_with_cached_sys_stdout()
    print('stderr is back', file=sys.stderr)
    

    stdout_redirected() redirects all output for sys.stdout.fileno() to a given filename, file object, or file descriptor (os.devnull in the example).

    stdout_redirected() and merged_stderr_stdout() are defined here.