Suppress Stdout/Stderr Print from Python Functions

Suppress stdout / stderr print from Python functions

This approach (found through the related sidebar) might work. It reassigns the file descriptors rather than just the wrappers to them in sys.stdout, etc.

How to use a `with` statement to suppress `sys.stdout` or `sys.stderr`?

I use something like this:

class Suppress:
def __init__(self, *, suppress_stdout=False, suppress_stderr=False):
self.suppress_stdout = suppress_stdout
self.suppress_stderr = suppress_stderr
self.original_stdout = None
self.original_stderr = None

def __enter__(self):
import sys, os
devnull = open(os.devnull, "w")

# Suppress streams
if self.suppress_stdout:
self.original_stdout = sys.stdout
sys.stdout = devnull

if self.suppress_stderr:
self.original_stderr = sys.stderr
sys.stderr = devnull

def __exit__(self, *args, **kwargs):
import sys
# Restore streams
if self.suppress_stdout:
sys.stdout = self.original_stdout

if self.suppress_stderr:
sys.stderr = self.original_stderr

Example:

import sys
print("Before")
with Suppress(suppress_stdout=True):
print("Inside")
print("After")

print("Before", file=sys.stderr)
with Suppress(suppress_stderr=True):
print("Inside", file=sys.stderr)
print("After", file=sys.stderr)

Output:


Before
After
Before
After

Notes:

  • I put my imports inside methods for cleanliness, but usually this would be inside a module file with imports at the top.
  • Suppressing stderr is risky, especially because of the way I'm (not) handling exceptions in the __exit__ method. You might look into crafting a more robust exit method.

Silence the stdout of a function in Python without trashing sys.stdout and restoring each function call

Assigning the stdout variable as you're doing has no effect whatsoever, assuming foo contains print statements -- yet another example of why you should never import stuff from inside a module (as you're doing here), but always a module as a whole (then use qualified names). The copy is irrelevant, by the way. The correct equivalent of your snippet is:

import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout

Now, when the code is correct, is the time to make it more elegant or fast. For example, you could use an in-memory file-like object instead of file 'trash':

import sys
import io
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
foo()
sys.stdout = save_stdout

for elegance, a context is best, e.g:

import contextlib
import io
import sys

@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
yield
sys.stdout = save_stdout

once you have defined this context, for any block in which you don't want a stdout,

with nostdout():
foo()

More optimization: you just need to replace sys.stdout with an object that has a no-op write method. For example:

import contextlib
import sys

class DummyFile(object):
def write(self, x): pass

@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = DummyFile()
yield
sys.stdout = save_stdout

to be used the same way as the previous implementation of nostdout. I don't think it gets any cleaner or faster than this;-).

Suppressing R script's output

If you want to completely suppress all stderr messages, put this line early in your script:

sink(file("/dev/null", "w"), type="message")

Obviously this isn't going to help with debugging...

How to block calls to print?

Python lets you overwrite standard output (stdout) with any file object. This should work cross platform and write to the null device.

import sys, os

# Disable
def blockPrint():
sys.stdout = open(os.devnull, 'w')

# Restore
def enablePrint():
sys.stdout = sys.__stdout__


print 'This will print'

blockPrint()
print "This won't"

enablePrint()
print "This will too"

If you don't want that one function to print, call blockPrint() before it, and enablePrint() when you want it to continue. If you want to disable all printing, start blocking at the top of the file.

How to suppress console output in Python?

Here's the relevant block of code from joystick.c (via SVN at http://svn.seul.org/viewcvs/viewvc.cgi/trunk/src/joystick.c?view=markup&revision=2652&root=PyGame)

    value = SDL_JoystickGetHat (joy, _index);
#ifdef DEBUG
printf("SDL_JoystickGetHat value:%d:\n", value);
#endif
if (value & SDL_HAT_UP) {

Looks like a problem with having debugging turned on.

How to suppress or capture the output of subprocess.run()?

Here is how to suppress output, in order of decreasing levels of cleanliness. They assume you are on Python 3.

  1. You can redirect to the special subprocess.DEVNULL target.
import subprocess

subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL)
# The above only redirects stdout...
# this will also redirect stderr to /dev/null as well
subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Alternatively, you can merge stderr and stdout streams and redirect
# the one stream to /dev/null
subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)

  1. If you want a fully manual method, can redirect to /dev/null by opening the file handle yourself. Everything else would be identical to method #1.
import os
import subprocess

with open(os.devnull, 'w') as devnull:
subprocess.run(['ls', '-l'], stdout=devnull)

Here is how to capture output (to use later or parse), in order of decreasing levels of cleanliness. They assume you are on Python 3.

NOTE: The below examples use text=True.

  • This causes the STDOUT and STDERR to be captured as str instead of bytes.
    • Omit text=True to get bytes data
  • text=True is Python >= 3.7 only, use universal_newlines=True on Python <= 3.6
    • universal_newlines=True is identical to text=True but more verbose to type but should exist on all Python versions
  1. If you simply want to capture both STDOUT and STDERR independently, AND you are on Python >= 3.7, use capture_output=True.
import subprocess

result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
print(result.stderr)

  1. You can use subprocess.PIPE to capture STDOUT and STDERR independently. This works on any version of Python that supports subprocess.run.
import subprocess

result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, text=True)
print(result.stdout)

# To also capture stderr...
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)
print(result.stderr)

# To mix stdout and stderr into a single string
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
print(result.stdout)


Related Topics



Leave a reply



Submit