<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hello Ian,<div><br></div><div>I really like your proposal.</div><div><br></div><div>Massimo<br><div><br></div><div><br><div><div>On Sep 22, 2009, at 9:22 PM, Ian Bicking wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">OK, I mentioned this in the last thread, but... I can't keep up with all this discussion, and I bet you can't either.<br><br>So, here's a rough proposal for WSGI and unicode:<br><br>I propose we switch primarily to "native" strings: str on both Python 2 and 3.<br> <br>Specifically:<br><br>environ keys: native<br>environ CGI values: native<br>wsgi.* (that is text): native<br>response status: native<br>response headers: native<br><br>wsgi.input remains byte-oriented, as does the response app_iter.<br> <br>I then propose that we eliminate SCRIPT_NAME and PATH_INFO.&nbsp; Instead we have:<br><br>wsgi.script_name<br>wsgi.path_info (I'm not entirely set on these names)<br><br>These both form the original path.&nbsp; It is not URL decoded, so it should be ASCII.&nbsp; (I believe non-ASCII could be rejected by the server, with Bad Request?&nbsp; A server could also choose to treat it as UTF8 or Latin1 and encode unsafe characters to make it ASCII)&nbsp; Thus to re-form the URL, you do:<br> <br>environ['wsgi.url_scheme'] + '://' + environ['HTTP_HOST'] + environ['wsgi.script_name'] + environ['wsgi.path_info'] + '?' + environ['QUERY_STRING']<br><br>All incoming headers will be treated as Latin1.&nbsp; If an application suspects another encoding, it is up to the application to transcode the header into another encoding.&nbsp; The transcoded value should not be put into the environ.&nbsp; In most cases headers should be ASCII, and Latin1 is simply a fallback that allows all bytes to be represented in both Python 2 and 3.<br> <br>Similarly all outgoing headers will be Latin1.&nbsp; Thus if you (against good sense) decide to put UTF8 into a cookie, you can do:<br><br>headers.append(('Set-Cookie', unicode_text.encode('UTF8').decode('latin1')))<br> <br>The server will then decode the text as latin1, sending the UTF8 bytes.&nbsp; This is lame, but non-ASCII in headers is lame.&nbsp; It would be preferable to do:<br><br>headers.append(('Set-Cookie', urllib.quote(unicode_text.encode('UTF8'))))<br> <br>This sends different text, but is highly preferable.&nbsp; If you wanted to parse a cookie that was set as UTF8, you'd do:<br><br>parse_cookie(environ['HTTP_COOKIE'].encode('latin1').decode('utf8'))<br> <br>Again, it would be better to do;<br><br>parse_cookie(urllib.unquote(environ['HTTP_COOKIE']).decode('utf8'))<br><br>Other variables like environ['wsgi.url_scheme'], environ['CONTENT_TYPE'], etc, will be native strings.&nbsp; A Python 3 hello work app will then look like:<br> <br>def hello_world(environ):<br>&nbsp;&nbsp;&nbsp; return ('200 OK', [('Content-type', 'text/html; charset=utf8')], ['Hello World!'.encode('utf8')])<br><br>start_response and changes to wsgi.input are incidental to what I'm proposing here (except that wsgi.input will be bytes); we can decide about themseparately. <br clear="all"> <br><br><br>Outstanding issues:<br><br>Well, the biggie: is it right to use native strings for the environ values, and response status/headers?&nbsp; Specifically, tricks like the latin1 transcoding won't work in Python 2, but will in Python 3.&nbsp; Is this weird?&nbsp; Or just something you have to think about when using the two Python versions?<br> <br>What happens if you give unicode text in the response headers that cannot be encoded as Latin1?<br><br>Should some things specifically be ASCII?&nbsp; E.g., status.<br><br>Should some things be unicode on Python 2?<br><br> Is there a common case here that would be inefficient?<br><br><br><br> -- <br>Ian Bicking &nbsp;| &nbsp;<a href="http://blog.ianbicking.org" target="_blank">http://blog.ianbicking.org</a> &nbsp;| &nbsp;<a href="http://topplabs.org/civichacker" target="_blank">http://topplabs.org/civichacker</a><br> <span>&lt;ATT00001..txt></span></blockquote></div><br></div></div></body></html>