Home > Software design >  Ensure that error messages are printed last in Python
Ensure that error messages are printed last in Python

Time:08-24

This must have an answer somewhere but I couldn't find it.

I would like my error/exception messages to be the last thing printed to the terminal, but it seems random whether they come out before all the text I have printed, after all the text I have printed, or somewhere in the middle of it.

I though a solution would be to use sys.stdout.flush(), so I tried the following:

if __name__ == '__main__':
    import sys
    try:
        main()
    except:
        sys.stdout.flush()
        raise

..But this doesn't work for some reason, it is still seemingly random in which order the error message and the text I have printed comes out.

Why? and how do I fix this?

EDIT: Here is a minimal reproducible example, which behaves as described above at least on my system:

import sys
import numpy as np


def print_garbage():
    print(''.join(map(chr, np.random.randint(0, 256, 100))))
    raise Exception


try:
    print_garbage()
except:
    sys.stdout.flush()
    raise

EDIT: I am running Python version 3.10.0 on a windows machine, and the terminal I am using is the cmd through PyCharm terminal. My PyCharm version is Community version 2022.2

CodePudding user response:

You can print traceback to stdout, so that there will be no out-of-sync problem:

import traceback
import sys

try:
    print_garbage()
except:
    traceback.print_exc(file=sys.stdout)

CodePudding user response:

stdout and stderr are separate channels. stdout is a buffered channel and stderr is unbuffered. This is why you are seeing the stderr message before the stdout one. Python is outputting them in your desired order, but the stdout data is being buffered before it is printed.

See here for how to disable buffering.

  • Related