Issue Details (XML | Word | Printable)

Key: MODPYTHON-15
Type: Improvement Improvement
Status: Reopened Reopened
Priority: Minor Minor
Assignee: Nicolas Lehuen
Reporter: Nicolas Lehuen
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
mod_python

Publisher : iterable return values should be corretly published

Created: 29/Jan/05 09:14 PM   Updated: 13/Aug/06 07:49 AM
Return to search
Component/s: None
Affects Version/s: 3.1.3
Fix Version/s: None

Time Tracking:
Not Specified


 Description  « Hide
Suppose this function in a published module :

def index(req)
    req.content_type = 'text/plain'
    yield '1\n'
    yield '2\n'
    yield '3\n'
    yield '4\n'

When published, this module should return a text content with '1\n2\n3\n4\n'.

This could also be useful with a file() object, since they are iterable ; this would provide another way to send a file, only slightly less performing than the send_file() method. Handy when you want to filter a file :

def filter(req,filename):
    f = open(filename,'r')
    for line in f:
        yield re.sub('foo','bar',line)


 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Graham Dumpleton added a comment - 13/Feb/05 10:53 AM
I would be worried here about cases where a generator/iterator of this form never actually had a stop condition. Imagine something which continually generates random numbers (if that makes sense). If mod_python were to just keep calling it to generate all data, it would eventually blow up. Seems to me to be safer for mod_python not to do anything with generators/iterators at all and make the user wrap them as appropriate to extract all the required data.

Note, I could be talking nonsense here as I have never consciously used generators so making some assumptions about them. :-)

Graham Dumpleton added a comment - 13/Feb/05 11:20 AM
The PEP on generators actually gives an example which if accessible would cause mod_python to blow up if mod_python kept calling it until all values were exhausted. Ie.,

   def fib():
            a, b = 0, 1
            while 1:
                yield b
                a, b = b, a+b

Thus, safer to make users wrap it in ordinary Python code and collect data themselves and then put it together as required.

Nicolas Lehuen added a comment - 13/Feb/05 07:38 PM
Nobody prevents anyone from putting an infinite loop in a standard publisher, either. This would cause mod_python to blow up :

dex index(req):
    while True:
        req.write('foobar\n')

So we don't need to worry about the possibility that some code written by a developer goes into an infinite loop. I really think that the advantages of iterator publication outweight this particular drawback.


Nicolas Lehuen made changes - 01/May/05 07:28 PM
Field Original Value New Value
Status Open [ 1 ] In Progress [ 3 ]
Repository Revision Date User Message
ASF #201794 Sat Jun 25 22:18:48 UTC 2005 nlehuen New publishing code for the publisher.

- Solves MODPYTHON-15 "iterable return values should be corretly published"
- Also takes care of selecting a proper encoding when the returned objects are Unicode strings. It parses the Content-Type header to select the encoding, or chooses UTF-8 if no encoding is given.
- Returning nothing is now allowed. Nothing is returned to the client.

Unit tests have been made to ensure that there was no regression.
Files Changed
MODIFY /httpd/mod_python/trunk/test/htdocs/tests.py
MODIFY /httpd/mod_python/trunk/lib/python/mod_python/publisher.py
MODIFY /httpd/mod_python/trunk/test/test.py
MODIFY /httpd/mod_python/trunk/src/include/mpversion.h

Nicolas Lehuen added a comment - 26/Jun/05 07:19 AM
Fixed in subversion.

Nicolas Lehuen made changes - 26/Jun/05 07:19 AM
Fix Version/s 3.2.0 [ 11060 ]
Status In Progress [ 3 ] Resolved [ 5 ]
Resolution Fixed [ 1 ]
Repository Revision Date User Message
ASF #355725 Sat Dec 10 09:16:06 UTC 2005 nlehuen Reverted MODPYTHON-15 to fix MODPYTHON-97 ; we'll get back to this in mod_python 3.3.
Files Changed
MODIFY /httpd/mod_python/trunk/lib/python/mod_python/publisher.py
MODIFY /httpd/mod_python/trunk/test/test.py
MODIFY /httpd/mod_python/trunk/Doc/appendixc.tex

Nicolas Lehuen added a comment - 10/Dec/05 06:16 PM
Reopened to fix MODPYTHON-97.

Nicolas Lehuen made changes - 10/Dec/05 06:16 PM
Resolution Fixed [ 1 ]
Status Resolved [ 5 ] Reopened [ 4 ]
Nicolas Lehuen added a comment - 10/Dec/05 06:18 PM
It's a little bit more complicated than expected, because it breaks some RPC / JSON code (which rely on str() being called on tuples or lists)... Plus we should implement chunked encoding when returning content produced by iterators, since we can't set the Content-Length header upfront.

Nicolas Lehuen made changes - 10/Dec/05 06:18 PM
Fix Version/s 3.3 [ 12310101 ]
Environment
Fix Version/s 3.2 [ 11060 ]
Description Suppose this function in a published module :

def index(req)
    req.content_type = 'text/plain'
    yield '1\n'
    yield '2\n'
    yield '3\n'
    yield '4\n'

When published, this module should return a text content with '1\n2\n3\n4\n'.

This could also be useful with a file() object, since they are iterable ; this would provide another way to send a file, only slightly less performing than the send_file() method. Handy when you want to filter a file :

def filter(req,filename):
    f = open(filename,'r')
    for line in f:
        yield re.sub('foo','bar',line)
Suppose this function in a published module :

def index(req)
    req.content_type = 'text/plain'
    yield '1\n'
    yield '2\n'
    yield '3\n'
    yield '4\n'

When published, this module should return a text content with '1\n2\n3\n4\n'.

This could also be useful with a file() object, since they are iterable ; this would provide another way to send a file, only slightly less performing than the send_file() method. Handy when you want to filter a file :

def filter(req,filename):
    f = open(filename,'r')
    for line in f:
        yield re.sub('foo','bar',line)
Graham Dumpleton made changes - 13/Aug/06 07:49 AM
Fix Version/s 3.3 [ 12310101 ]