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