Author v+python
Recipients amaury.forgeotdarc, barry, eric.araujo, erob, flox, ggenellina, giampaolo.rodola, gvanrossum, l0nwlf, oopos, pebbe, quentel, r.david.murray, tcourbon, tercero12, tobias, v+python
Date 2011-01-02.21:16:40
SpamBayes Score 4.27966e-09
Marked as misclassified No
Message-id <1294003006.72.0.978579722864.issue4953@psf.upfronthosting.co.za>
In-reply-to
Content
Pierre, thanks for your work on this.  I hope a fix can make it in to 3.2.

However, while starting Python with -u can help a but, that should not, in my opinion, be requirement to use CGI.  Rather, the stdin should be set into binary mode by the CGI processing... it would be helpful if the CGI module either did it automatically, verified it has been done, or at least provided a helper function that could do it, and that appropriate documentation be provided, if it is not automatic.  I've seen code like:

    try: # Windows needs stdio set for binary mode.
        import msvcrt
        msvcrt.setmode (0, os.O_BINARY) # stdin  = 0
        msvcrt.setmode (1, os.O_BINARY) # stdout = 1
        msvcrt.setmode (2, os.O_BINARY) # stderr = 2
    except ImportError:
        pass

and

        if hasattr( sys.stdin, 'buffer'):
            sys.stdin = sys.stdin.buffer

which together, seem to do the job.  For output, I use a little class that accepts either binary or text, encoding the latter:

    class IOMix():
        def __init__( self, fh, encoding="UTF-8"):
            if hasattr( fh, 'buffer'):
                self._bio = fh.buffer
                fh.flush()
                self._last = 'b'
                import io
                self._txt = io.TextIOWrapper( self.bio, encoding, None, '\r\n')
                self._encoding = encoding
            else:
                raise ValueError("not a buffered stream")
        def write( self, param ):
            if isinstance( param, str ):
                self._last = 't'
                self._txt.write( param )
            else:
                if self._last == 't':
                    self._txt.flush()
                self._last = 'b'
                self._bio.write( param )
        def flush( self ):
            self._txt.flush()
        def close( self ):
            self.flush()
            self._txt.close()
            self._bio.close()


        sys.stdout = IOMix( sys.stdout, encoding )
        sys.stderr = IOMix( sys.stderr, encoding )


IOMix may need a few more methods for general use, "print" comes to mind, for example.
History
Date User Action Args
2011-01-02 21:16:46v+pythonsetrecipients: + v+python, gvanrossum, barry, amaury.forgeotdarc, ggenellina, giampaolo.rodola, eric.araujo, r.david.murray, oopos, tercero12, tcourbon, tobias, flox, l0nwlf, pebbe, quentel, erob
2011-01-02 21:16:46v+pythonsetmessageid: <1294003006.72.0.978579722864.issue4953@psf.upfronthosting.co.za>
2011-01-02 21:16:40v+pythonlinkissue4953 messages
2011-01-02 21:16:40v+pythoncreate