def test_deep_recursion(): def fact(n, result=1): if n <= 1: returnValue(result) else: noreturn(fact(n - 1, n * result)) yield assert deferred_result(coroutine(fact)(1)) == 1 assert deferred_result(coroutine(fact)(10)) == safe_fact(10) with recursion_limit(100): try: # +10 is actually too high here as we probably already have some stuff on the stack, but just to be sure assert deferred_result(coroutine(fact)(110)) == safe_fact(110) except RuntimeError: assert False # ...and now let's prove that the same (tail call optimizable) algorithm without noreturn will eat up the stack def normal_fact(n, result=1): if n <= 1: returnValue(result) else: return normal_fact(n - 1, n * result) with recursion_limit(100): try: normal_fact(110) except RuntimeError: pass else: assert False, "normal_fact(110)"
def loadCommands(self): commands = {} path = yield self.config.get("path","commands") for loader, name, ispkg in pkgutil.iter_modules([path]): if ispkg: continue try: command = getattr(__import__(path, fromlist=[name.encode("utf8")]), name) reload(command) command.config["name"] = name command.config["command"] = coroutine(command.command) if inspect.isgeneratorfunction(command.command) else command.command args, varg, vkwarg, kwargs = inspect.getargspec(command.command) if args[:5] != ["guid", "manager", "irc", "channel", "user"]: continue if kwargs: boundary = -1 * len(kwargs) command.config["args"] = args[5:boundary] command.config["kwargs"] = args[boundary:] else: command.config["args"] = args[5:] command.config["kwargs"] = [] command.config["varg"] = varg command.config["vkwarg"] = vkwarg if "disabled" in command.config and command.config["disabled"]: continue commands[name] = command.config except: self.err("Failed to load {}.{}", path, name) self.commands = commands
def __new__(self, name, bases, dict_): """Verifies that the run method is a generator, and wraps it with `txcoroutine.coroutine`.""" ret = super(ProcessType, self).__new__(self, name, bases, dict_) path_of_new_class = dict_['__module__'] + '.' + name if path_of_new_class != 'spinoff.actor.process.Process': if not inspect.isgeneratorfunction(ret.run): raise TypeError("Process.run must return a generator") ret.run = coroutine(ret.run) return ret
def loadCommands(self): commands = {} path = yield self.config.get("path", "commands") for loader, name, ispkg in pkgutil.iter_modules([path]): if ispkg: continue try: command = getattr( __import__(path, fromlist=[name.encode("utf8")]), name) reload(command) command.config["name"] = name command.config["command"] = coroutine( command.command) if inspect.isgeneratorfunction( command.command) else command.command args, varg, vkwarg, kwargs = inspect.getargspec( command.command) if args[:5] != ["guid", "manager", "irc", "channel", "user"]: continue if kwargs: boundary = -1 * len(kwargs) command.config["args"] = args[5:boundary] command.config["kwargs"] = args[boundary:] else: command.config["args"] = args[5:] command.config["kwargs"] = [] command.config["varg"] = varg command.config["vkwarg"] = vkwarg if "disabled" in command.config and command.config["disabled"]: continue commands[name] = command.config except: self.err("Failed to load {}.{}", path, name) self.commands = commands