Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Grzeliński <grzelinskimat@gmail.com>2020-08-19 13:24:30 +0300
committerMateusz Grzeliński <grzelinskimat@gmail.com>2020-08-19 13:24:30 +0300
commit430df0c4b7194050e5a2b6bec58bb0998a8be2ec (patch)
tree434140304b217fb009f052813ba81e57d7d74611 /source/blender
parent9d29b49a57921f8ec71ea88919d94c4334de6566 (diff)
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
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/python/intern/bpy_interface_inoutwrapper.c24
-rw-r--r--source/blender/python/intern/bpy_interface_run.c79
2 files changed, 90 insertions, 13 deletions
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));