#!/usr/bin/env python """ miniclass.py - Coroutine Generators Authors: tav, sbp Derived from: http://trac.espnow.net/file/sandbox/tav/2weeks/pyutil/coroutine/coroutine.py http://svn.espnow.net/svnroot/sandbox/tav/2weeks/pyutil/coroutine/coroutine.py http://irclogs.espnow.net/esp.artifex/2005.02.27.log License: Public domain """ import inspect from string import Template minigen = Template(""" def $name$original: m = type('Miniclass', (object,), $name.__gen__.__dict__)() m.__iter__ = lambda self: self m.next = $name.__gen__$replaced.next return m """) def miniclass(generator): name = generator.__name__ args, varargs, varkw = inspect.getargs(generator.func_code) args[0] = 'm' original = inspect.formatargspec(args[1:], varargs, varkw) replaced = inspect.formatargspec(args, varargs, varkw) store = {} exec(minigen.substitute(locals()), generator.func_globals, store) m = store[name] m.__doc__ = generator.__doc__ m.__gen__ = generator return m @miniclass def countdown(self, n): """Countdown from n to 0. Example: >>> c = countdown(10) >>> c.next() 10 >>> c.next() 9 >>> c.next() 8 >>> c.n = 3 >>> c.next() 2 >>> c.next() 1 """ self.n = n while (self.n > 0): yield self.n self.n -= 1 class Debugger(object): def __init__(self, globals, locals): self.globals = globals self.locals = locals def write(self, code): code = code.rstrip('\r\n') if code: print '>>>', code try: print eval(code, self.globals, self.locals) except SyntaxError: exec(code + '\n', self.globals, self.locals) debugger = Debugger(globals(), locals()) def test(): print >> debugger, 'c = countdown(10)' print >> debugger, 'c.next()' print >> debugger, 'c.next()' print >> debugger, 'c.next()' print >> debugger, 'c.n = 3' print >> debugger, 'c.next()' print >> debugger, 'c.next()' def main(): import doctest doctest.testmod() if __name__=="__main__": main()