I'm writing a few unit tests of some code which uses sys.stderr.write to report errors in input. This is as it should be, but this clobbers the unit test output. Is there any way to tell Python to not output error messages for single commands, à la 2> /dev/null
?
I suggest writing a context manager:
import contextlib
import sys
@contextlib.contextmanager
def nostderr():
savestderr = sys.stderr
class Devnull(object):
def write(self, _): pass
def flush(self): pass
sys.stderr = Devnull()
try:
yield
finally:
sys.stderr = savestderr
Now, wrap any code snippet whose stderr you want suppressed in a with nostderr():
and you have the localized, temporary, guaranteed-reversible stderr suppression that you want.
__enter__
and __exit__
isn't hard of course, but this way, for sufficiently simple cases, you have even less boilerplate code to write and read;-). –
Gravitate sys.stderr = os.devnull
–
Ingeingeberg You could create a dummy file object that did nothing with its output, and set stderr to that:
class NullWriter:
def write(self, s):
pass
sys.stderr = NullWriter()
If you only want to quiet stderr for a specific duration, you can use a with
statement like so:
class Quieter:
def __enter__(self):
self.old_stderr = sys.stderr
sys.stderr = NullWriter()
def __exit__(self, type, value, traceback):
sys.stderr = self.old_stderr
with Quieter():
# Do stuff; stderr will be suppressed, and it will be restored
# when this block exits
Requires Python 2.6 or higher, or you can use it in Python 2.5 with a from __future__ import with_statement
.
Another possibility (besides assigning to sys.stderr
) is to structure your code to write errors to a file provided, but to default that file to sys.stderr. Then you can provide a DevNull writer during testing.
If you do want to reassign sys.stderr, you can use the unittest framework to manage it for you:
class DevNull(object):
def write(self, data):
pass
class MyTestCase(unittest.TestCase):
def setUp(self):
self.old_stderr = sys.stderr
sys.stderr = DevNull()
def tearDown(self):
sys.stderr = self.old_stderr
This way, every test dev-null's stderr, but then restores it at the end of the test.
class DevNull(object):
def write(self, data): pass
sys.stderr = DevNull()
To have a less permanent solution, one could figure out something like as follows:
_stderr = None
def quiet():
global _stderr
if _stderr is None:
_stderr = sys.stderr
sys.stderr = DevNull()
def verbose():
global _stderr
if _stderr is not None:
sys.stderr = _stderr
_stderr = None
Function names can probably be better
quiet(...)
? –
Templin © 2022 - 2024 — McMap. All rights reserved.