I've subclassed InteractiveInterpreter in an attempt to make it friendlier for use in a remote console for a C++ app. What I really wanted to do was wrap/adapt the base class's runsource() method to return a 2-tuple (more, result) where 'more' is a bool indicating whether a complete command was recognized, and 'result' is a string representing the results of evaluating the last chunk (which may be empty, or may contain an error message).
The only fool-proof way I found to do this was to redirect stdout/ stderr during calls to the base class's runsource() method. If I only provide custom sys.displayhook and sys.excepthook replacements, then any print statements the user enters go to the host app's stdout: >>> print xvis.get_object(17).pos instead of being captured and echoed back to the remote console. If I omit the print, it does what I expect: >>> xvis.get_object(17).pos >>> (11.7, 1005.0, 0.0) But I'd really like to: 1) Get rid of this slight difference to the normal python REPL 2) Not have to redirect stdout/stderr (I'm afraid other [C++] threads may compete with python for these streams.) I thought I could get away with import print_function from __future__ (see example code below), but my re-pointed print function never gets called. I think I'm just naive about how exec() works. Is it hard-wired to stdout or something? *Should* this even work? Any insight much appreciated! - Dave Wolfe ---------- from __future__ import print_function ... class HookContext(object): def __init__(self, printhook, displayhook, excepthook): self.printhook = printhook self.displayhook = displayhook self.excepthook = excepthook def __enter__(self): print = self.printhook sys.displayhook = self.displayhook sys.excepthook = self.excepthook def __exit__(self, exc_type, exc_value, traceback): print = __builtins__.print sys.displayhook = sys.__displayhook__ sys.excepthook = sys.__excepthook__ class Interpreter(InteractiveInterpreter): [ ... lots of stuff omitted ...] def do_runsource(self, source): self.output.reset() self.output.truncate() with HookContext(self.printhook self.displayhook, self.excepthook): try: more = InteractiveInterpreter.runsource(self, source) result = self.output.getvalue() except (EOFError, OverflowError, SyntaxError): pass return more, result -- http://mail.python.org/mailman/listinfo/python-list