Proxy the response iter to make generator code run before return.
[wrw.git] / wrw / dispatch.py
CommitLineData
b409a338
FT
1__all__ = ["restart"]
2
3class restart(Exception):
4 def handle(self, req):
5 pass
6
7def mangle(result):
8 try:
9 iter(result)
10 except TypeError:
11 pass
12 else:
13 return result
14 return [str(result)]
15
e8aa9ce2
FT
16class iterproxy(object):
17 # Makes sure iter(real).next() is called immediately, in order to
18 # let generator code run.
19 def __init__(self, real):
20 self.bk = real
21 self.bki = iter(real)
22 self._next = [None]
23 self.next()
24
25 def __iter__(self):
26 return self
27
28 def next(self):
29 if self._next is None:
30 raise StopIteration()
31 ret = self._next[0]
32 try:
33 self._next[:] = [self.bki.next()]
34 except StopIteration:
35 self._next = None
36 return ret
37
38 def close(self):
39 if hasattr(self.bk, "close"):
40 self.bk.close()
41
b409a338
FT
42def handle(req, startreq, handler):
43 try:
44 resp = [""]
45 while True:
46 try:
e8aa9ce2 47 resp = iterproxy(handler(req))
b409a338
FT
48 break
49 except restart, i:
d7604bee 50 handler = i.handle
b409a338
FT
51 req.commit(startreq)
52 return resp
53 finally:
54 req.cleanup()