Fixed python3 iterator protocol.
[wrw.git] / wrw / dispatch.py
1 __all__ = ["restart"]
2
3 class restart(Exception):
4     def handle(self, req):
5         pass
6
7 def mangle(result):
8     try:
9         iter(result)
10     except TypeError:
11         pass
12     else:
13         return result
14     return [str(result)]
15
16 class 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
42 def handle(req, startreq, handler):
43     try:
44         resp = [""]
45         while True:
46             try:
47                 resp = iterproxy(handler(req))
48                 break
49             except restart as i:
50                 handler = i.handle
51         req.commit(startreq)
52         return resp
53     finally:
54         req.cleanup()