[Python-ideas] Replacing the standard IO streams (was Re: changing sys.stdout encoding)

Nick Coghlan ncoghlan at gmail.com
Sun Jun 10 15:16:24 CEST 2012

On Sun, Jun 10, 2012 at 5:17 PM, Antoine Pitrou <solipsis at pitrou.net> wrote:
> Le 10/06/2012 04:26, Nick Coghlan a écrit :
>> Calling detach() on the standard streams is a bad idea - the interpreter
>> uses the originals internally, and calling detach() breaks them.
> Where does it do that? The interpreter certainly shouldn't hardwire the
> original objects internally.

At the very least, sys.__std(in/out/err)__.  Doing "sys.stderr =
io.TextIOWrapper(sys.stderr.detach(), line_buffering=True)" also seems
to suppress display of exception tracebacks at the interactive prompt
(perhaps the default except hook is using a cached reference?). I
believe PyFatalError and other APIs that are used deep in the
interpreter won't respect the module level setting.

Basically, it's dangerous to use detach() on a stream where you don't
hold the sole reference, and the safest approach with the standard
streams is to assume that other code is holding references to them.
Detaching the standard streams is just as likely to cause problems as
closing them.

> Moreover, your snippet is wrong because if someone replaces the streams for
> a second time, garbage collecting the previous streams will close the file
> descriptors. You should use closefd=False.

True, although that nicety is all the more reason to encapsulate this
idiom in a new IOBase.reopen() method:

    def reopen(self, mode=None, buffering=-1, encoding=None,
errors=None, newline=None, closefd=False):
        if mode is None:
            mode = getattr(mode, self, 'r')
        return open(self.fileno(), mode, buffering, encoding, errors,
newline, closefd)


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list