Commit: 430df0c4b7194050e5a2b6bec58bb0998a8be2ec
Author: Mateusz Grzeliński
Date:   Wed Aug 19 12:24:30 2020 +0200
Branches: soc-2020-info-editor
https://developer.blender.org/rB430df0c4b7194050e5a2b6bec58bb0998a8be2ec

Restore patch with catching python stdout after merge

Restored implementation with minor tweaks:
- now catching python output works for files (including not saved ones) and 
strings

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

M       source/blender/python/intern/bpy_interface_inoutwrapper.c
M       source/blender/python/intern/bpy_interface_run.c

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

diff --git a/source/blender/python/intern/bpy_interface_inoutwrapper.c 
b/source/blender/python/intern/bpy_interface_inoutwrapper.c
index 3757e970948..910a0f65532 100644
--- a/source/blender/python/intern/bpy_interface_inoutwrapper.c
+++ b/source/blender/python/intern/bpy_interface_inoutwrapper.c
@@ -21,11 +21,9 @@
  */
 
 #include <Python.h>
+#include <stdbool.h>
 
-#include "MEM_guardedalloc.h"
-
-#include "BLI_string_utf8.h"
-#include "BLI_utildefines.h"
+#include <BLI_assert.h>
 
 #include "bpy_interface_inoutwrapper.h"
 
@@ -36,21 +34,25 @@ PyObject *stderr_backup = NULL;
 PyObject *string_io_buf = NULL;
 PyObject *string_io_getvalue = NULL;
 
-/* TODO (grzelins) move this whole implementation to bpy_capi_utils? */
 bool BPY_intern_init_io_wrapper()
 {
+  BLI_assert(string_io_mod == NULL);
+  BLI_assert(string_io == NULL);
+  BLI_assert(stderr_backup == NULL);
+  BLI_assert(stdout_backup == NULL);
+  BLI_assert(string_io_buf == NULL);
+  BLI_assert(string_io_getvalue == NULL);
   PyImport_ImportModule("sys");
   stdout_backup = PySys_GetObject("stdout"); /* borrowed */
   stderr_backup = PySys_GetObject("stderr"); /* borrowed */
-  BLI_assert(stderr_backup != NULL);
 
   if (!(string_io_mod = PyImport_ImportModule("io"))) {
     return false;
   }
-  else if (!(string_io = PyObject_CallMethod(string_io_mod, "StringIO", 
NULL))) {
+  if (!(string_io = PyObject_CallMethod(string_io_mod, "StringIO", NULL))) {
     return false;
   }
-  else if (!(string_io_getvalue = PyObject_GetAttrString(string_io, 
"getvalue"))) {
+  if (!(string_io_getvalue = PyObject_GetAttrString(string_io, "getvalue"))) {
     return false;
   }
   Py_INCREF(stdout_backup);  // since these were borrowed we don't want them 
freed when replaced.
@@ -75,13 +77,15 @@ PyObject *BPY_intern_get_io_buffer()
 
 void BPY_intern_free_io_twrapper()
 {
-  Py_DECREF(stdout_backup);  // since these were borrowed we don't want them 
freed when replaced.
+  Py_DECREF(stdout_backup);
   Py_DECREF(stderr_backup);
   Py_DECREF(string_io_mod);
   Py_DECREF(string_io_getvalue);
-  Py_DECREF(string_io); /* free the original reference */
+  Py_DECREF(string_io);
   stdout_backup = NULL;
   stderr_backup = NULL;
   string_io_buf = NULL;
   string_io_getvalue = NULL;
+  string_io_mod = NULL;
+  string_io = NULL;
 }
diff --git a/source/blender/python/intern/bpy_interface_run.c 
b/source/blender/python/intern/bpy_interface_run.c
index a7593ae7d79..5b7bd18e97c 100644
--- a/source/blender/python/intern/bpy_interface_run.c
+++ b/source/blender/python/intern/bpy_interface_run.c
@@ -20,6 +20,8 @@
 
 #include <stdio.h>
 
+#include <BKE_report.h>
+#include <CLG_log.h>
 #include <Python.h>
 
 #include "MEM_guardedalloc.h"
@@ -43,6 +45,8 @@
 #include "bpy_traceback.h"
 
 #include "../generic/py_capi_utils.h"
+#include "bpy.h"
+#include "bpy_interface_inoutwrapper.h"
 
 /* -------------------------------------------------------------------- */
 /** \name Private Utilities
@@ -96,10 +100,16 @@ static bool python_script_exec(
 
   PyC_MainModule_Backup(&main_mod);
 
-  if (text) {
-    char fn_dummy[FILE_MAXDIR];
-    bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text);
+  bool wrapper_init_ok = BPY_intern_init_io_wrapper();
+  if (!wrapper_init_ok) {
+    CLOG_WARN(
+        BPY_LOG_RNA,
+        "Setting python IO wrapper failed! Script output will not be visible 
in Info Editor");
+  }
 
+  char fn_dummy[FILE_MAXDIR];
+  bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text);
+  if (text) {
     if (text->compiled == NULL) { /* if it wasn't already compiled, do it now 
*/
       char *buf;
       PyObject *fn_dummy_py;
@@ -167,6 +177,31 @@ static bool python_script_exec(
     }
   }
 
+  if (wrapper_init_ok) {
+    /* printing io buffer will fail if error is set */
+    if (PyErr_Occurred()) {
+      PyObject *error_type, *error_value, *error_traceback;
+      PyErr_Fetch(&error_type, &error_value, &error_traceback);
+      PyErr_Clear();
+      PyObject *pystring = BPY_intern_get_io_buffer();
+      BKE_reportf(reports,
+                  RPT_INFO,
+                  "Python output from \"%s\":\n%s",
+                  fn ? fn : fn_dummy,
+                  _PyUnicode_AsString(pystring));
+      PyErr_Restore(error_type, error_value, error_traceback);
+    }
+    else {
+      PyObject *pystring = BPY_intern_get_io_buffer();
+      BKE_reportf(reports,
+                  RPT_INFO,
+                  "Python output from \"%s\":\n%s",
+                  fn ? fn : fn_dummy,
+                  _PyUnicode_AsString(pystring));
+    }
+    BPY_intern_free_io_twrapper();
+  }
+
   if (!py_result) {
     if (text) {
       if (do_jump) {
@@ -246,6 +281,13 @@ static bool bpy_run_string_impl(bContext *C,
 
   py_dict = PyC_DefaultNameSpace("<blender string>");
 
+  bool wrapper_init_ok = BPY_intern_init_io_wrapper();
+  if (!wrapper_init_ok) {
+    CLOG_WARN(
+        BPY_LOG_RNA,
+        "Setting python IO wrapper failed! Script output will not be visible 
in Info Editor");
+  }
+
   if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
     Py_DECREF(py_dict);
     retval = NULL;
@@ -254,6 +296,37 @@ static bool bpy_run_string_impl(bContext *C,
     retval = PyRun_String(expr, mode, py_dict, py_dict);
   }
 
+  if (wrapper_init_ok) {
+    /* printing io buffer will fail if error is set */
+    if (PyErr_Occurred()) {
+      PyObject *error_type, *error_value, *error_traceback;
+      PyErr_Fetch(&error_type, &error_value, &error_traceback);
+      PyErr_Clear();
+      PyObject *pystring = BPY_intern_get_io_buffer();
+      if (pystring != NULL) {
+        BKE_reportf(CTX_wm_reports(C),
+                    RPT_INFO,
+                    "Python output from running: \"%s\":\n%s",
+                    expr,
+                    _PyUnicode_AsString(pystring));
+        Py_DecRef(pystring);
+      }
+      PyErr_Restore(error_type, error_value, error_traceback);
+    }
+    else {
+      PyObject *pystring = BPY_intern_get_io_buffer();
+      if (pystring != NULL) {
+        BKE_reportf(CTX_wm_reports(C),
+                    RPT_INFO,
+                    "Python output from running \"%s\":\n%s",
+                    expr,
+                    _PyUnicode_AsString(pystring));
+        Py_DecRef(pystring);
+      }
+    }
+    BPY_intern_free_io_twrapper();
+  }
+
   if (retval == NULL) {
     ok = false;
     BPy_errors_to_report(CTX_wm_reports(C));

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to