diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-09-08 06:14:24 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-09-08 06:14:24 +0400 |
commit | 5a900be4d685b9b038327e49c4c5da948e1ba2ad (patch) | |
tree | 8c83841164fdf56d0e4c6631eed9a4c29c8ea946 /source | |
parent | 290ad64a222a09aec8cb2645942863b68c86e95d (diff) |
attempt to have a threadsafe version of PyC_ExceptionBuffer didnt work with UI script errors, reverting r39886.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/python/generic/py_capi_utils.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index b7e67ec5a93..a1571dc028c 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -209,6 +209,10 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) } /* returns the exception string as a new PyUnicode object, depends on external traceback module */ +#if 0 + +/* this version uses traceback module but somehow fails on UI errors */ + PyObject *PyC_ExceptionBuffer(void) { PyObject *traceback_mod= NULL; @@ -236,6 +240,78 @@ error_cleanup: return ret; } +#else /* verbose, non-threadsafe version */ +PyObject *PyC_ExceptionBuffer(void) +{ + PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */ + PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */ + PyObject *string_io = NULL; + PyObject *string_io_buf = NULL; + PyObject *string_io_mod= NULL; + PyObject *string_io_getvalue= NULL; + + PyObject *error_type, *error_value, *error_traceback; + + if (!PyErr_Occurred()) + return NULL; + + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + PyErr_Clear(); + + /* import io + * string_io = io.StringIO() + */ + + if(! (string_io_mod= PyImport_ImportModule("io")) ) { + goto error_cleanup; + } + else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) { + goto error_cleanup; + } + else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) { + goto error_cleanup; + } + + Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced. + Py_INCREF(stderr_backup); + + PySys_SetObject("stdout", string_io); // both of these are free'd when restoring + PySys_SetObject("stderr", string_io); + + PyErr_Restore(error_type, error_value, error_traceback); + PyErr_Print(); /* print the error */ + PyErr_Clear(); + + string_io_buf = PyObject_CallObject(string_io_getvalue, NULL); + + PySys_SetObject("stdout", stdout_backup); + PySys_SetObject("stderr", stderr_backup); + + Py_DECREF(stdout_backup); /* now sys owns the ref again */ + Py_DECREF(stderr_backup); + + Py_DECREF(string_io_mod); + Py_DECREF(string_io_getvalue); + Py_DECREF(string_io); /* free the original reference */ + + PyErr_Clear(); + return string_io_buf; + + +error_cleanup: + /* could not import the module so print the error and close */ + Py_XDECREF(string_io_mod); + Py_XDECREF(string_io); + + PyErr_Restore(error_type, error_value, error_traceback); + PyErr_Print(); /* print the error */ + PyErr_Clear(); + + return NULL; +} +#endif + /* string conversion, escape non-unicode chars, coerce must be set to NULL */ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) |