I have a context manager defined for the purpose of "silencing" the output of some Python code by redefining stdout and stderr temporarily.
When devnull is defined in the main function of the code, the output of the code is silenced successfully, however, when devnull is defined in the context manager, the output of the code is not silenced.
Why is this? How could the context manager silence the output while also defining devnull?
import os
import sys
def main():
print("hello")
devnull = open(os.devnull, "w")
with silence(
stdout = devnull,
stderr = devnull
):
print("there")
print("world")
class silence(object):
def __init__(
self,
stdout = None,
stderr = None
):
if stdout == None and stderr == None:
devnull = open(os.devnull, "w")
self._stdout = stdout or sys.stdout
self._stderr = stderr or sys.stderr
def __enter__(
self
):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.old_stdout.flush()
self.old_stderr.flush()
sys.stdout = self._stdout
sys.stderr = self._stderr
def __exit__(
self,
exc_type,
exc_value,
traceback
):
self._stdout.flush()
self._stderr.flush()
sys.stdout = self.old_stdout
sys.stderr = self.old_stderr
if __name__ == "__main__":
main()
In your __ init __
method, when the stderr
and stdout
arguments are None
you define devnull
but you do not assign this value to stderr
and stdout
. Consequently stderr
and stdout
are falsey and so the output streams remain as sys.stderr
and sys.stdout
.
class silence(object):
def __init__(
self,
stdout = None,
stderr = None
):
if stdout == None and stderr == None:
devnull = open(os.devnull, "w")
# Assign devnull to stdout and stderr
stdout = devnull
stderr = devnull
self._stdout = stdout or sys.stdout
self._stderr = stderr or sys.stderr