D
Dave W.
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:
instead of being captured and echoed back to the remote console.
If I omit the print, it does what I expect:
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
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:
instead of being captured and echoed back to the remote console.
If I omit the print, it does what I expect:
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