[Web-SIG] Returned application object and fileno.
Alan Kennedy
py-web-sig at xhaus.com
Wed Sep 1 19:08:46 CEST 2004
Phillip,
I'm fairly sure I understand your position now. But I think I don't
agree with it ;-)
[Phillip J. Eby]
> "File-like" is a complete red herring: the spec has never supported them
> (and IMO never will).
>
> What the spec calls for is an *iterable*: an object that can be used in
> a "for" loop. In Python 2.2 and up, file objects are iterable. In
> older versions of Python, they are not.
>
> Thus, an application that returns a file object implicitly requires
> Python 2.2 or up. (This issue is mentioned in the spec, where it warns
> that if you are using an older version of Python, you may *not* return a
> file object.)
>
> WSGI does not support returning files or file-like objects: it is simply
> an artifact of Python 2.2 and up that returning a file works at all!
My position here is that the iterator-ness of a returned file object is
secondary when the returned object has a fileno() method: most cpython
framework code is going to do this
if (hasattr(app_object, 'fileno') and callable(app_object.fileno):
send_file(app_object)
else:
treat_app_object_as_iterable(app_object)
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()".
> The fact that you would like such code to run in a Jython 2.1 server
> doesn't mean that the spec should expand its scope to cover even *file
> objects*, let alone "file-like" objects. It simply means that you'll
> have to deal with the special cases that entails, until Jython 2.2 is
> ready for prime-time.
Call me old-fashioned, but I'm a great believer in "practicality beats
purity". I think we should be seeking to be as inclusive as possible,
which means supporting as wide a software base as possible.
I'm just afraid that people will steam ahead writing WSGI middleware
applications which return file-objects, 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:
do_file_stuff(app_return)
[Alan Kennedy]
>> 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.
> You're effectively arguing for removing the 'fileno()' special case
> altogether, or else adding language to require the server to *first*
> check for iterability and raise an error if the return isn't iterable,
> so that running a 2.2 app in a 2.1 server won't "accidentally" succeed
> when the 2.1 server supports 'fileno()'.
Not at all.
I'm arguing for us to be practical about applications returning file
objects.
1. It's a very common use case
2. It's trivial to deal with
3. There are no python version dependency issues
In cpython frameworks, the code would look like this
if hasattr(app_object, 'fileno'):
do_file_stuff(app_object.fileno())
else:
do_iterator_stuff(app_object)
On jython
if type(app_object) is types.FileType:
do_file_stuff(app_object)
else:
do_iterator_stuff(app_object)
Is that so difficult to accept?
[Phillip J. Eby]
> I applaud your bravery in trying to make it work for Jython, but
> changing the spec to allow other kinds of objects isn't going to
> decrease the amount of work you have to do, only increase it for other
> people who *aren't* trying to support 2.2 apps in a server running under
> Python 2.1.
It's not really about bravery, it's about wanting to maximize
portability between available python platforms. I hope to achieve that
through the application of a little pythonic simplicity.
After all, we're just trying to move byte streams from one place to
another: do we have to be this complex about it?
> It's not about "file-like" objects, only *actual* file objects.
> Returning a "file-like" object offers no meaningful performance boost,
> and it is *not* supported -- and never was.
Except when it is supported, for whatever complicated reasons, e.g.
iterable objects with fileno()s.
[Alan Kennedy]
>> 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.
> That is why this is a Python versioning issue, and specific to your
> attempt to run 2.2 code in a 2.1 Python. It has absolutely nothing to
> do with accepting "file-like" objects in the spec, which never accepted
> them, nor is it intended to ever do so.
>
> Is this getting any clearer?
Crystal.
However, I think the absolute insistence on return objects being
iterable is slightly arbitrary and unnecessarily constraining.
I understand your desire to keep the spec clean and simple, and also
your desire to use modern python facilities to do it. But those modern
python facilities are not universally available, and, strictly speaking,
not absolutely required. I'm suppose I'm just pleading for a little
pythonic practicality.
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?
Lastly, since the spec is still potentially a moving target, I've
translated as much of my java as possible into jython, which will
greatly speed up the prototyping process. Once the spec is finalized, I
may translate it back to java, if there is a sufficient
performance/other requirement for that. (I should have prototyped it in
jython from the start, and saved myself a load of time).
Kind regards,
Alan.
More information about the Web-SIG
mailing list