This is normal behavior for output streams in most languages: they are buffered, i.e.
write actually writes to a buffer in memory and this buffer is written out to the stream in batches. Stdout is line buffered when writing to a terminal (i.e. an actual write takes place every time a newline is printed) but fully buffered (the data is written to memory until the memory buffer gets full) when writing to a regular file or a pipe. Stderr is either unbuffered or line buffered.
In Python, you can choose the type of buffering when opening a file, but not for the standard streams. If you want all streams to be unbuffered, you can set the
PYTHONUNBUFFERED environment variable to force the standard streams to be unbuffered. Alternatively, you can run the program under
But if your program doesn't emit output in an appropriate order when stdout is redirected, that's a defect in the program, which you should fix. In particular, if you're going to emit an error message that concerns output written to stdout, you should flush stdout first:
sys.stderr.write('Bad stuff happened\n')