[Bf-blender-cvs] [d8a998c] master: Use contextlib for temporary py console overrides

Campbell Barton noreply at git.blender.org
Thu Feb 4 07:50:58 CET 2016


Commit: d8a998ce71f5dafa1f5681158bad8225ca289408
Author: Campbell Barton
Date:   Thu Feb 4 17:40:02 2016 +1100
Branches: master
https://developer.blender.org/rBd8a998ce71f5dafa1f5681158bad8225ca289408

Use contextlib for temporary py console overrides

Using context overrides means stdout/stderr overrides can't be left set by accident.

===================================================================

M	release/scripts/modules/console_python.py

===================================================================

diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py
index 59e4f23..64bb002 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)




More information about the Bf-blender-cvs mailing list