We're back after a server migration that caused effbot.org to fall over a bit harder than expected. Expect some glitches.

Why doesn't closing sys.stdout (stdin, stderr) really close it?

Python file objects are a high-level layer of abstraction on top of C stdio streams, which in turn are a medium-level layer of abstraction on top of (among other things) low-level C file descriptors.

For most file objects you create in Python via the builtin open constructor, calling close marks the Python file object as being closed from Python’s point of view, and also arranges to close the underlying C stream. This also happens automatically in f‘s destructor, when f becomes garbage.

But stdin, stdout and stderr are treated specially by Python, because of the special status also given to them by C. Calling sys.stdout.close marks the Python-level file object as being closed, but does not close the associated C stream.

To close the underlying C stream for one of these three, you should first be sure that this is what you really want to do (e.g., you may confuse extension modules trying to do I/O). If it is, use os.close:

os.close(0)   # close C's stdin stream
os.close(1)   # close C's stdout stream
os.close(2)   # close C's stderr stream

CATEGORY: library