Unbuffered stdout in python (as in python -u) from within the program
Question:
Is there any way to get the effect of running python -u
from within my code? Failing that, can my program check if it is running in -u
mode and exit with an error message if not? This is on Linux (Ubuntu 8.10 Server).
Answers:
Assuming you’re on Windows:
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
… and on Unix:
fl = fcntl.fcntl(sys.stdout.fileno(), fcntl.F_GETFL)
fl |= os.O_SYNC
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, fl)
(Unix copied in from commented solution, rather than linking.)
EDIT (Oct 2020). As pointed out in a note to this answer, in Python3, stderr is buffered too.
You might use the fact that stderr is never buffered and try to redirect stdout to stderr:
import sys
#buffered output is here
doStuff()
oldStdout = sys.stdout
sys.stdout = sys.stderr
#unbuffered output from here on
doMoreStuff()
sys.stdout = oldStdout
#the output is buffered again
doEvenMoreStuff()
The best I could come up with:
>>> import os
>>> import sys
>>> unbuffered = os.fdopen(sys.stdout.fileno(), 'w', 0)
>>> unbuffered.write('test')
test>>>
>>> sys.stdout = unbuffered
>>> print 'test'
test
Tested on GNU/Linux. It seems it should work on Windows too. If I knew how to reopen sys.stdout, it would be much easier:
sys.stdout = open('???', 'w', 0)
References:
http://docs.python.org/library/stdtypes.html#file-objects
http://docs.python.org/library/functions.html#open
http://docs.python.org/library/os.html#file-object-creation
[Edit]
Note that it would be probably better to close sys.stdout before overwriting it.
You could always pass the -u parameter in the shebang line:
#!/usr/bin/python -u
Is there any way to get the effect of running python -u
from within my code? Failing that, can my program check if it is running in -u
mode and exit with an error message if not? This is on Linux (Ubuntu 8.10 Server).
Assuming you’re on Windows:
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
… and on Unix:
fl = fcntl.fcntl(sys.stdout.fileno(), fcntl.F_GETFL)
fl |= os.O_SYNC
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, fl)
(Unix copied in from commented solution, rather than linking.)
EDIT (Oct 2020). As pointed out in a note to this answer, in Python3, stderr is buffered too.
You might use the fact that stderr is never buffered and try to redirect stdout to stderr:
import sys
#buffered output is here
doStuff()
oldStdout = sys.stdout
sys.stdout = sys.stderr
#unbuffered output from here on
doMoreStuff()
sys.stdout = oldStdout
#the output is buffered again
doEvenMoreStuff()
The best I could come up with:
>>> import os
>>> import sys
>>> unbuffered = os.fdopen(sys.stdout.fileno(), 'w', 0)
>>> unbuffered.write('test')
test>>>
>>> sys.stdout = unbuffered
>>> print 'test'
test
Tested on GNU/Linux. It seems it should work on Windows too. If I knew how to reopen sys.stdout, it would be much easier:
sys.stdout = open('???', 'w', 0)
References:
http://docs.python.org/library/stdtypes.html#file-objects
http://docs.python.org/library/functions.html#open
http://docs.python.org/library/os.html#file-object-creation
[Edit]
Note that it would be probably better to close sys.stdout before overwriting it.
You could always pass the -u parameter in the shebang line:
#!/usr/bin/python -u