From d8a998ce71f5dafa1f5681158bad8225ca289408 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Feb 2016 17:40:02 +1100 Subject: Use contextlib for temporary py console overrides Using context overrides means stdout/stderr overrides can't be left set by accident. --- release/scripts/modules/console_python.py | 52 ++++++++++++++++--------------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'release') diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py index 59e4f2314d8..64bb002d6a1 100644 --- a/release/scripts/modules/console_python.py +++ b/release/scripts/modules/console_python.py @@ -136,33 +136,40 @@ def execute(context, is_interactive): console, stdout, stderr = get_console(hash(context.region)) - # redirect output - sys.stdout = stdout - sys.stderr = stderr - - # don't allow the stdin to be used, can lock blender. - stdin_backup = sys.stdin - sys.stdin = None - if _BPY_MAIN_OWN: main_mod_back = sys.modules["__main__"] sys.modules["__main__"] = console._bpy_main_mod - # in case exception happens - line = "" # in case of encoding error - is_multiline = False + # redirect output + from contextlib import ( + redirect_stdout, + redirect_stderr, + ) + + # not included with Python + class redirect_stdin(redirect_stdout.__base__): + _stream = "stdin" - try: - line = line_object.body + # don't allow the stdin to be used, can lock blender. + with redirect_stdout(stdout), \ + redirect_stderr(stderr), \ + redirect_stdin(None): - # run the console, "\n" executes a multi line statement - line_exec = line if line.strip() else "\n" + # in case exception happens + line = "" # in case of encoding error + is_multiline = False - is_multiline = console.push(line_exec) - except: - # unlikely, but this can happen with unicode errors for example. - import traceback - stderr.write(traceback.format_exc()) + try: + line = line_object.body + + # run the console, "\n" executes a multi line statement + line_exec = line if line.strip() else "\n" + + is_multiline = console.push(line_exec) + except: + # unlikely, but this can happen with unicode errors for example. + import traceback + stderr.write(traceback.format_exc()) if _BPY_MAIN_OWN: sys.modules["__main__"] = main_mod_back @@ -174,8 +181,6 @@ def execute(context, is_interactive): output_err = stderr.read() # cleanup - sys.stdout = sys.__stdout__ - sys.stderr = sys.__stderr__ sys.last_traceback = None # So we can reuse, clear all data @@ -213,9 +218,6 @@ def execute(context, is_interactive): if output_err: add_scrollback(output_err, 'ERROR') - # restore the stdin - sys.stdin = stdin_backup - # execute any hooks for func, args in execute.hooks: func(*args) -- cgit v1.2.3