0

How can I truncate sys.stderr due to exception handling?

import sys
try:
    sys.stderr.write('Someone written here')
    raise Exception
except:
    # would like to clean sys.stderr here
    sys.stderr.write('I only want this')
    sys.exit(1)

I would like standard error to contains only the string "I only want this"

Plinio.Santos
  • 1,709
  • 24
  • 31

1 Answers1

2

Would something like this help you? It would only work if you had only printed a single line to stderr so far: Python - Remove and Replace Printed items

The other way to do it would just be to append stderr to a string and print it in a finally, though this would not allow you to print incrementally in real time.

import sys

stderr_str = ''
try:
    stderr_str += 'Someone written here'
    raise Exception
except:
    # would like to clean sys.stderr here
    stderr_str = ''
    stderr_str += 'I only want this'
finally:
    sys.stderr.write(stderr_str)

Edit: You could also try redefining stderr to a file-like object, as is detailed in this answer. This should work even if third part modules write to stderr.

Example:

bash-3.2$ ls
a.py    b.py
bash-3.2$ cat a.py
import sys
import b

sys.stderr = open('stderr.log', 'a')
b.raise_exception()

bash-3.2$ cat b.py
def raise_exception():
    return 1/0

bash-3.2$ python a.py
bash-3.2$ ls
a.py        b.py        b.pyc       stderr.log
bash-3.2$ cat stderr.log
Traceback (most recent call last):
  File "a.py", line 5, in <module>
    b.raise_exception()
  File "/Users/username/tmp2/b.py", line 2, in raise_exception
    return 1/0
ZeroDivisionError: integer division or modulo by zero

You could basically use a technique like this to capture all the stderr until the end, and then either write it to stderr, or just ignore it and write your new output to stderr.

Community
  • 1
  • 1
Christopher Shroba
  • 7,006
  • 8
  • 40
  • 68
  • The stderr is being written by an third party module, as well as the exception raised. So this would not be an option to me – Plinio.Santos Nov 18 '16 at 14:47
  • It worked, thanks! Just in case you want to update your aswer, after doing `sys.stderr = open('stderr.log', 'a')` I'm able to call `sys.stderr.truncate()`. It was not possible using the standard sys.strerr – Plinio.Santos Nov 18 '16 at 16:58