[Web-SIG] Returned application object and fileno.
Phillip J. Eby
pje at telecommunity.com
Wed Sep 1 19:42:04 CEST 2004
At 06:08 PM 9/1/04 +0100, Alan Kennedy wrote:
>I would summarise the position of the current spec as "you must return an
>iterable, except when you want to return a file object, which will work
>fine under cpython 2.2+, because files are iterable under cpython 2.2+,
>even though they don't need to be iterable when they have fileno()".
No, it's just that you must return an iterable, *period*. The fact that
2.2 allows this to be a file object is irrelevant, as is the fact that 2.1
doesn't allow this to be a file object. There are thousands of classes out
there for both 2.1 and 2.2 that either are, or aren't, iterable, and that's
>I'm just afraid that people will steam ahead writing WSGI middleware
>applications which return file-objects,
The part you keep leaving out is that such middleware is thereby targeted
at Python 2.2, not 2.1. The spec explicitly mentions this.
>which will fail on jython simply because putting the following lines in my
>code is a violation of the spec
>if type(app_return) is types.FileType:
What you're doing here isn't a "violation", IMO, merely "out of
scope". It's not up to the spec to explain how to make Python 2.1 support
2.2 features; IMO, that's all you're doing here, and it doesn't hurt anybody.
> >> 2. The spec, as is, explicitly permits authors of cpython applications
> >> to return file-like objects,
>[Phillip J. Eby]
> > Only if they are *iterable*, which is only true of the 'file' object in
> > 2.2 and up.
>Which seems to me an arbitrary criterion, especially in the light that the
>iterator nature of the file object will possibly (likely) not be actually
>used, as described in the snippet above.
The CGI runner won't use fileno(), and neither will many other servers. I
don't see how the "iterable" criterion is arbitrary because some objects
are iterable and others aren't. Any criterion we choose will by definition
include some objects and not others.
>In cpython frameworks, the code would look like this
>if hasattr(app_object, 'fileno'):
>if type(app_object) is types.FileType:
>Is that so difficult to accept?
But that's exactly what the spec says to do *now*, except that it doesn't
explicitly bless the type check. If you really want to have that blessing
written into the spec, so be it. I just don't see it as a matter that's in
scope of the spec, because it's not only Jython-specific, but specific to
your server as well. Document your extension as you would any such
extension. There's no law against being more *permissive* than the spec
I do not see any reason to burden *other* server authors by requiring them
to support your extension, because no use cases have been presented for
this for any situation *other* than a Jython 2.1 server trying to run a
Python 2.2 application.
> >> I think we should explicitly allow return of a file-like object, and
> >> thus freedom to use the read() method, etc.
>[Phillip J. Eby]
> > You are trying to let 2.2 code run in a 2.1 Python.
>Well, I see it as WSGI forcing me to jump through hoops in order to
>support the notion of iterability, even when that notion is NOT
>universally applicable, as the fileno() exception proves.
It's stretching a 2.2 spec to work with older versions of Python, largely
intended for your benefit, as you were the first person who presented a
strong use case for supporting *any* pre-2.2 version of Python.
>However, I think the absolute insistence on return objects being iterable
>is slightly arbitrary and unnecessarily constraining.
For whom? I've given numerous examples of how trivial it is for code
targeted to 2.1 or earlier to support making files and even file-like
objects into iterables. This is a small burden for those who want their
code to be portable to such versions.
Similarly, it's not an unreasonable burden for your server to support
extensions to 2.1 behavior in order to accommodate code not written for
Python 2.1 compatibility.
It *is* unreasonable to expand the spec to place those burdens on people
who don't care about supporting 2.1, or who don't care about supporting 2.2
code under 2.1
>Maybe I'm just wasting my time? Maybe I'm the only one who is interested
>in seeing a jython WSGI server into which users can drop universal WSGI
>components and have them just work? Is anyone else interested in such a
>jython WSGI container? Or should I just toddle off back to J2EE servlets?
I agree with your intentions; I just don't agree that *other* server
authors should be forced to duplicate your efforts if they don't have that
use case. Iterability is the single simplest protocol that is universally
accessible in any Python used in the last several years. It doesn't
require any introspection. Currently, the common case code for a server
looks like this:
result = application(environ, start_response)
for data in result:
This is perfectly valid implementation under the spec. Changing the spec
to allow the application to return anything *but* iterables means
complicating *every* server, for the sole benefit of applications that want
to use 2.2 idioms under Python 2.1.
If I were a server author targeting 2.2 and up (and I will be), I would
rightly object to adding extra introspection to the above, when it will not
benefit me or any user in my target audience. If my server requires 2.2,
then obviously applications running under it can safely use 2.2
idioms. And if they're written for 2.1 they also work.
So here's the resolution: I will slightly expand the section on supporting
older versions of Python, to explicitly allow a 2.1 server to
"forward-compatibly" check for 2.2 idioms such as returning a file object.
I'd prefer not to do that, but not because I dislike the approach. We're
in "violent agreement" on what *your* server should do about this, and I
encourage you to implement it. Our disagreement (as I understand it) is that:
1. I think this is a "server-specific extension" that's outside the spec's
scope to rule on the validity of, and
2. I don't think that requiring others to do what your code will be doing
is a good idea, because they don't *need* to, unless they're trying to run
2.2 code on a 2.1 Python, which should *definitely* not be a requirement of
More information about the Web-SIG