|
Nick
nick at dd.revealed.net
Mon Apr 17 14:57:56 EDT 2006
As an example to follow up on this, in your XSLT parser, you would have:
for streamlet in filter:
filter.req.passes += 1
streambuffer.write(streamlet.replace('\r\n', '\n'))
("if streamlet is None" is not required at this point)
Maybe what I neglected to convey is that the multiple calls to the
outputfilter handler would abstracted differently, so that to the handler it
would appear to be called only a single time, with the mod_python code
handling the feeding of the filter iterator via the apache bucket brigade.
Not having studied this code very carefully, I don't know how complicated
it's going to be, but it would certainly simplify things a lot on the Python
side of things. The trick is going to be writing the __iter__ function of
the filter object in such a way that it will yield the results of a read(),
unless the read is '', in which case it will wait for the next filter call,
finally stopping the iteration once the last read() is done.
Nick
Nick wrote:
> An iterator would take care of these kinds of questions internally.
> Yielding '' does not signal the last iteration, nor should it according to
> your example. However, None should not be yielded by the iterator, and
> would instead raise a StopIteration (or simply fall through to the end of
> the __iter__ function, though being in C probably easier to raise
> StopInteration).
>
> In other words, you don't need the support code below. You only need the
> for, which will end when None has been returned from the read(), now hidden
> in the iterator.
>
> Nick
>
> Lee Brown wrote:
>> That's a good question. I don't know if the filter object is iterable or
>> not.
>>
>> What's warping my noodle is handling the two different exit conditions in a
>> Pythonic way; if the filter returns '' you just want to hibernate but if the
>> filter returns None you want to wrap up and get out. Kinda like this (given
>> an iterable filter object):
>>
>> for streamlet in filter:
>> if streamlet:
>> streambuffer.write(streamlet)
>> else:
>> break
>> If streamlet is None:
>> [proceed with your filter thing]
>>
>> To me, this does not seem to be much more Pythonic that the previous version
>> - you still have to noodle on it a while to see the flow structure.
>>
>>
>> Best Regards,
>> Lee E. Brown
>> (administrator at leebrown.org)
>>
>> -----Original Message-----
>> From: mod_python-bounces at modpython.org
>> [mailto:mod_python-bounces at modpython.org] On Behalf Of Nick
>> Sent: Monday, April 17, 2006 12:43 PM
>> To: Lee Brown
>> Cc: mod_python at modpython.org
>> Subject: Re: [mod_python] Output Filters Redeaux
>>
>> Great example! Thanks.
>>
>> On a devel note, it looks like the filter object would be very handy if it
>> could be treated as in iterator, such as (using the sample code's
>> nomenclature):
>>
>> for streamlet in filter:
>> [do something with streamlet here]
>>
>> It would definitely turn filter writing into something more Pythonic. Does
>> that seem like something that would be useful?
>>
>> Thanks,
>> Nick
>>
>> Lee Brown wrote:
>>> Greetings!
>>>
>>> Just for fun, here is a handy template for constructing Mod Python
>>> output filters:
>>>
>>> from mod_python import apache
>>> from cStringIO import StringIO
>>>
>>> def outputfilter (filter):
>>>
>>> try:
>>> streambuffer = filter.req.streambuffer
>>> except AttributeError:
>>> filter.req.streambuffer = StringIO() # See Note 1
>>> streambuffer = filter.req.streambuffer
>>> # See Note 2
>>>
>>> streamlet = filter.read()
>>> while streamlet:
>>> # See Note 3
>>> streambuffer.write(streamlet)
>>> streamlet = filter.read()
>>>
>>> if streamlet is None:
>>> # See Note 4
>>> filter.write(streambuffer)
>>> filter.close()
> _______________________________________________
> Mod_python mailing list
> Mod_python at modpython.org
> http://mailman.modpython.org/mailman/listinfo/mod_python
|