#! python3
from contextlib import redirect_stderr
import io
f = io.StringIO()
with redirect_stderr(f):
# simulates an error
erd
As seen above, I have used the redirect_stderr
function to redirect stderr to a StringIO
object. However, it doesn't work, as the error message is still printed out in command prompt:
Traceback (most recent call last):
File "C:\Users\max\testerr.py", line 8, in <module>
erd
NameError: name 'erd' is not defined
I tested it on Python 3.5.1
64 bit and 3.5.2
64 bit with the same results.
A similar issue in this thread
I have also tried writing the error to a file as described in the linked thread, but the file is empty after running the script.
You need to actually write to stderr, it is not a tool to catch exceptions.
>>> from contextlib import redirect_stderr
>>> import io
>>> f = io.StringIO()
>>> import sys
>>> with redirect_stderr(f):
... print('Hello', file=sys.stderr)
...
>>> f.seek(0)
0
>>> f.read()
'Hello\n'
To catch exceptions, you need to do some more work. You can use a logging library (external), or write your own exception handler, and then use your custom output for it.
Here is something quick, which uses a logger instance to help write to the stream:
log = logging.getLogger('TEST')
log.addHandler(logging.StreamHandler(stream=f))
def exception_handler(exc_type, exc_value, exc_traceback):
if issubclass(exc_type, KeyboardInterrupt):
# Let the system handle things like CTRL+C
sys.__excepthook__(*args)
log.error('Exception: ', exc_info=(exc_type, exc_value, exc_traceback))
sys.excepthook = exception_handler
raise RuntimeError('foo')
Here f
is the same StringIO
instance from above. After you run this code, you should not see any traceback on your console, but it will be stored in the stream object:
>>> f.seek(0)
0
>>> print(f.read())
Hello
Exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: foo