diff options
author | Nils Philippsen <nils@redhat.com> | 2015-08-19 16:32:16 +0200 |
---|---|---|
committer | Nils Philippsen <nils@redhat.com> | 2015-08-19 16:32:16 +0200 |
commit | be901601473bd3ba5826d86fb9912843a3517a07 (patch) | |
tree | 0d3ae1654e6901f23fce39da78b4ec21cf201562 /paste/evalexception/evalcontext.py | |
download | paste-git-be901601473bd3ba5826d86fb9912843a3517a07.tar.gz |
Python 3: App must always return binary type.
Fixes tests.test_wsgiwrappers.test_wsgirequest_charset
Diffstat (limited to 'paste/evalexception/evalcontext.py')
-rw-r--r-- | paste/evalexception/evalcontext.py | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/paste/evalexception/evalcontext.py b/paste/evalexception/evalcontext.py new file mode 100644 index 0000000..42f2efa --- /dev/null +++ b/paste/evalexception/evalcontext.py @@ -0,0 +1,69 @@ +# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) +# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php +from six.moves import cStringIO as StringIO +import traceback +import threading +import pdb +import six +import sys + +exec_lock = threading.Lock() + +class EvalContext(object): + + """ + Class that represents a interactive interface. It has its own + namespace. Use eval_context.exec_expr(expr) to run commands; the + output of those commands is returned, as are print statements. + + This is essentially what doctest does, and is taken directly from + doctest. + """ + + def __init__(self, namespace, globs): + self.namespace = namespace + self.globs = globs + + def exec_expr(self, s): + out = StringIO() + exec_lock.acquire() + save_stdout = sys.stdout + try: + debugger = _OutputRedirectingPdb(save_stdout) + debugger.reset() + pdb.set_trace = debugger.set_trace + sys.stdout = out + try: + code = compile(s, '<web>', "single", 0, 1) + six.exec_(code, self.globs, self.namespace) + debugger.set_continue() + except KeyboardInterrupt: + raise + except: + traceback.print_exc(file=out) + debugger.set_continue() + finally: + sys.stdout = save_stdout + exec_lock.release() + return out.getvalue() + +# From doctest +class _OutputRedirectingPdb(pdb.Pdb): + """ + A specialized version of the python debugger that redirects stdout + to a given stream when interacting with the user. Stdout is *not* + redirected when traced code is executed. + """ + def __init__(self, out): + self.__out = out + pdb.Pdb.__init__(self) + + def trace_dispatch(self, *args): + # Redirect stdout to the given stream. + save_stdout = sys.stdout + sys.stdout = self.__out + # Call Pdb's trace dispatch method. + try: + return pdb.Pdb.trace_dispatch(self, *args) + finally: + sys.stdout = save_stdout |