Question: I want to hide stdout/stderr in a python script **BUT** the print is not done into the python script itself but inside the underlying .c extension when a python module needs one.

it is the case for *netsnmp* python module, it requires compilation, the problem is that there are some 'printf' directly into the C (client\_intf.c) code that I would like to capture and hide :

```
from netsnmp import *
import sys,os
devnull = open(os.devnull, 'w')
sys.stdout, sys.stderr = devnull, devnull
session = Session(DestHost='myhostthatdoesnotexisttogenerateerror',Version=2,Community='demopublic')

```

When I run it I still have some traces :

```
python test.py
getaddrinfo: myhostthatdoesnotexisttogenerateerror nodename nor servname provided, or not known
error:snmp_new_session: Couldn't open SNMP session

```

How can I get rid of these messages on stdout/stderr ? this is important because I am developping Nagios plugins, and I can afford such output (nevertheless, I want to capture them to raise a custom exception)

Answer: 
Eric's answer is excellent but it has an important drawback: if you already used `sys.stderr` to initialize some stuff it will become useless. As an example: if you created a custom error logger using `sys.stderr` it will stop working.

Here is a modified version:

```py
import os
from contextlib import contextmanager

@contextmanager
def hide_stderr():
    """ Low level stderr supression. """
    newstderr = os.dup(2)
    devnull = os.open('/dev/null', os.O_WRONLY)
    os.dup2(devnull, 2)
    os.close(devnull)
    yield
    os.dup2(newstderr, 2)

@contextmanager
def hide_stdout():
    """ Low level stdout supression. """
    newstderr = os.dup(1)
    devnull = os.open('/dev/null', os.O_WRONLY)
    os.dup2(devnull, 1)
    os.close(devnull)
    yield
    os.dup2(newstderr, 1)

import sys

my_stderr = sys.stderr
print("Test 1: no stderr, no stdout")
with hide_stderr():
    with hide_stdout():
        print("1 stdout")
        print("2 stderr", file=my_stderr)
print("Test 2: no stderr, but stdout")
with hide_stderr():
    print("1 stdout")
    print("2 stderr", file=my_stderr)
print("Test 3: stderr, no stdout")
with hide_stdout():
    print("1 stdout")
    print("2 stderr", file=my_stderr)
print("Test 4: stderr and stdout")
print("1 stdout")
print("2 stderr", file=my_stderr)

```

Note that the main difference is the use of `os.dup2` at the end. We recover the file descriptor from the copy we did and we don't mess with `sys.stderr`.
Here is the code to temporary block stdout and stderr :

```
from netsnmp import *
import sys,os

newstdout = os.dup(1)
newstderr = os.dup(2)
devnull = os.open('/dev/null', os.O_WRONLY)
os.dup2(devnull, 1)
os.dup2(devnull, 2)
os.close(devnull)
# stdout/stderr are blocked here
print "I will be back but nobody will know it"
session = Session(DestHost='myhostthatdoesnotexisttogenerateerror',Version=2,Community='demopublic')
sys.stdout = os.fdopen(newstdout, 'w')
sys.stderr = os.fdopen(newstderr, 'w')
# stdout/stderr are unblocked here
print "I'm back"

```