On Wed, Sep 23, 2009 at 2:38 PM, P.J. Eby <span dir="ltr">&lt;<a href="mailto:pje@telecommunity.com">pje@telecommunity.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="im">At 08:42 AM 9/23/2009 +0200, Armin Ronacher wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
&gt; I then propose that we eliminate SCRIPT_NAME and PATH_INFO.  Instead we<br>
&gt; have:<br>
IMO they should stick around for compatibility with older applications<br>
and be latin1 encoded on Python 3.  But the use is discouraged.<br>
</blockquote>
<br></div>
One or the other should be there, not both.  If you allow older code to work, this means it could change the old ones but not the new, leaving a confused mess for child applications to sort out.</blockquote><div><br>This is my strongly-held opinion as well.  It&#39;s been a struggle to get people to provide accurate SCRIPT_NAMEs, and to represent the idea of SCRIPT_NAME through SCRIPT_NAME (as opposed to a hodge-podge of different patterns, configuration, etc).  To provide this information twice would be a big step backwards, allowing for all sorts of weird bugs and inconsistent behavior when the two weren&#39;t in sync, and depending on which key is given preference in code.<br>
<br>I *wish* SCRIPT_NAME and PATH_INFO had been strictly required in WSGI 1 (they are in CGI, but not WSGI).  If they were, we&#39;d see more of environ[&#39;PATH_INFO&#39;], which would break fast and obviously, and less environ.get(&#39;PATH_INFO&#39;, &#39;&#39;).  But... too late for that now.  The new key should definitely be required.  Then code can even do:<br>
<br>if &#39;wsgi.path_info&#39; in environ:<br>    path_info = urllib.unquote(environ[&#39;wsgi.path_info&#39;]<br>else:<br>    path_info = environ.get(&#39;PATH_INFO&#39;, &#39;&#39;)<br><br>We should also make sure the new validator works on both versions of WSGI, which will make it easier to backport checks like making sure wsgi.path_info is *not* in a WSGI 1 environ.<br>
<br><br>Not directly in response to this email, several people expressed concern that some environments provide only the unquoted path.  I think it&#39;s not terribly horrible if they fake it by re-quoting the path.  In CGI/Python 3 this would be something like:<br>
<br>environ[&#39;wsgi.script_name&#39;] = urllib.request.quote(os.environ[&#39;SCRIPT_NAME&#39;].encode(sys.getdefaultencoding(), &#39;surrogateescape&#39;))<br><br>(obviously urllib.request.quote needs to be fixed to work on bytes; though the implementation is also small enough we could show the correct implementation in the spec, and warn implementors not to trust urllib.request.quote to work in Python 3.0-3.1.1)<br>
<br>I also believe you can safely reconstruct the real SCRIPT_NAME/PATH_INFO from REQUEST_URI, which is usually available (at least in contexts where this sort of thing is a problem).  I am not up to thinking it through right now, as it&#39;s not a trivial algorithm, but I&#39;m sure it can be done.  Really it&#39;s just a question of how much you can avoid brute force, because you could always do:<br>
<br>def real_path(request_uri, script_name, path_info):<br>    for i in range(request_uri):<br>        if urllib.request.unquote(request_uri[:i]) == script_name:<br>            return request_uri[:i], request_uri[i:]<br>    # Something is messed up, fake it<br>
    return urllib.request.quote(script_name), urllib.request.quote(path_info)<br><br>I think you could do better than character-by-character (instead by path segment), and in particular do it faster when %2f doesn&#39;t appear in the path at all (the common case).  This would be appropriate code for wsgiref.<br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">
<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
If we go about dropping start_response, can we move the app iter to the<br>
beginning?  That would be consistent with the signature of common<br>
response objects, making it possible to do this:<br>
<br>
    response = Response(*hello_world(environ))<br>
</blockquote>
<br></div>
When you say &quot;beginning&quot;, do you mean the beginning of the return tuple?  That is:<br>
<br>
    return [&#39;body here&#39;], &#39;200 OK&#39;, [(&#39;Header&#39;, &#39;value&#39;)]<br>
<br>
I&#39;d be surprised if a lot of response objects had such a signature, since that&#39;s not the order a server would actually output that data in.</blockquote><div><br>It&#39;d be more reasonable to change the Response __init__ signature, like:<br>
<br>class Response(object):<br>    def __init__(self, body_or_wsgi_response, status=None, headers=None):<br>        if isinstance(body_or_wsgi_response, tuple):<br>            status, headers, body = body_or_wsgi_response<br>
        else:<br>            body = body_or_wsgi_response<br> <br>If you allow an iterator for a body argument, it could be a tuple; but at least WebOb doesn&#39;t allow iterators, only str/unicode.  (You can give an iterator, but you need to do it with an app_iter keyword argument.)  I don&#39;t know what Werkzeug or other frameworks allow.<br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">
<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
In general I think doing too many changes at once is harmful<br>
</blockquote>
<br></div>
Actually, the reverse is true for standards.  Incremental change means more versions, which goes counter to the point of having a standard in the first place.</blockquote><div><br>Yeah; WSGI 1.1 is just errata, I expect to change very little code.  I&#39;d rather make just one change to WSGI 2.  And it doesn&#39;t seem so hard really.<br>
</div></div><br clear="all"><br>-- <br>Ian Bicking  |  <a href="http://blog.ianbicking.org">http://blog.ianbicking.org</a>  |  <a href="http://topplabs.org/civichacker">http://topplabs.org/civichacker</a><br>