def runInConsole(command, console, globalNS=None, localNS=None, filename=None, args=None, kw=None, unsafeTracebacks=False): """Run this, directing all output to the specified console. If command is callable, it will be called with the args and keywords provided. Otherwise, command will be compiled and eval'd. (Wouldn't you like a macro?) Returns the command's return value. The console is called with a list of (type, message) pairs for display, see L{IManholeClient.console}. """ output = [] fakeout = FakeStdIO("stdout", output) fakeerr = FakeStdIO("stderr", output) errfile = FakeStdIO("exception", output) code = None val = None if filename is None: filename = str(console) if args is None: args = () if kw is None: kw = {} if localNS is None: localNS = globalNS if (globalNS is None) and (not callable(command)): raise ValueError("Need a namespace to evaluate the command in.") try: out = sys.stdout err = sys.stderr sys.stdout = fakeout sys.stderr = fakeerr try: if callable(command): val = apply(command, args, kw) else: try: code = compile(command, filename, 'eval') except: code = compile(command, filename, 'single') if code: val = eval(code, globalNS, localNS) finally: sys.stdout = out sys.stderr = err except: (eType, eVal, tb) = sys.exc_info() fail = failure.Failure(eVal, eType, tb) del tb # In CVS reversion 1.35, there was some code here to fill in the # source lines in the traceback for frames in the local command # buffer. But I can't figure out when that's triggered, so it's # going away in the conversion to Failure, until you bring it back. errfile.write(pb.failure2Copyable(fail, unsafeTracebacks)) if console: fakeout.consolidate() console(output) return val