| 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() |