[Web-SIG] WSGI tests

Ian Bicking ianb at colorstudy.com
Wed Sep 29 19:23:54 CEST 2004


Phillip J. Eby wrote:
> Actually, it just occurred to me that there *is* a legitimate test you 
> can do for SCRIPT_NAME and PATH_INFO: at least *one* of them must be 
> present and non-blank, because if you're at the site root, SCRIPT_NAME 
> is empty and PATH_INFO has to be '/'.  (Or the other way around, the CGI 
> spec isn't clear on this, but Apache CGI puts the '/' in PATH_INFO.)  

OK... I guess the root of a domain is an odd case, because I can't 
imagine what the difference between SCRIPT_NAME="/", PATH_INFO="" or 
SCRIPT_NAME="", PATH_INFO="/" would mean.

On further thought, I think it doesn't make sense for SCRIPT_NAME to be 
"/".  Because PATH_INFO must always start with a "/", SCRIPT_NAME must 
be "" if there's any path (unless we get double /'s when reconstructing 
the URL, which wouldn't be good).  So I think I'm going to make the test 
include SCRIPT_NAME != "/".  The general case would say that SCRIPT_NAME 
should not end with a /, but I don't feel 100% confident that that's 
correct.

> Anyway, it's never valid to have both empty or missing, so you can:
> 
>     assert environ.get('SCRIPT_NAME') or environ.get('PATH_INFO')
> 
> Also, if present and non-empty, both of these variables must *begin* 
> with a '/', so it's more like:
> 
>     script_name = environ.get('SCRIPT_NAME','')
>     path_info   = environ.get('PATH_INFO','')
>     assert not script_name or script_name.startswith('/')
>     assert not path_info   or path_info.startswith('/')
>     assert script_name or path_info

Yes, the '/' tests were already in there.

>>> By the way, I found another issue with lint: IteratorWrapper doesn't 
>>> close the original iterable if it had a close() method.
>>
>>
>> Fixed as well.
> 
> 
> Actually, no.  Lint's iterator close() is still broken.  You have to use 
> close() on the *iterable*, not on iter(iterable).  The two may be 
> different objects, since an iterable may return a separate iterator object.

This was something I felt a little ambiguous about.  I assume the server 
always must iterate over iter(app_iter), it can't iterate over app_iter 
directly.  When using a "for" loop there's not much distinction, but if 
you access the .next() methods directly there would be.  Anyway, I'm a 
little fuzzy when __iter__ gets called implicitly.  I was suprised that 
it seemed to get called twice when iterating with a simple for look, and 
I had to add IteratorWrapper.__iter__.

> Also, pycgiwrapper returns None from __call__, when it should return an 
> iterator.  A simple way to fix that would be to just 'return [body]' 
> after calling start_respsonse.

I've added a check in lint specifically for None or False for the 
iterator; it would still fail implicitly before, but this way the error 
should be better.  I haven't tested pycgiwrapper yet, or some of the 
other code I wrote before, so there might be other bugs in there (e.g., 
unnecessary use of write(), or returning None).

> I'm pretty much coming to the conclusion that WSGI is no longer 
> "simple", alas.  For it to actually be usable, there's going to have to 
> be a reference library, as well as tests.  I'm going to keep pecking 
> away at your lint program, and eventually your other test facilities as 
> well, so that I'll have something to test the reference library with.  :)

The basic mechanics are still reasonably simple, but there's a lot of 
smaller things to consider.  So I don't think WSGI has become that much 
more complicated, we've just come to appreciate complexities that were 
there all along.

Also, should we be putting all of this code in a single repository?

-- 
Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org


More information about the Web-SIG mailing list