diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-09-03 10:46:31 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-09-03 10:46:31 +0400 |
commit | 8cc307b4f2d2e1321ab8ec1baee6697ae3b0a967 (patch) | |
tree | 1d4ab146209246000cae8677b225881511f53c3e | |
parent | 60dcfe25269ff9709c784f6f44c9b0273e73c786 (diff) |
PyC_ExceptionBuffer is now threadsafe, used for converting exceptions into reports.
-rw-r--r-- | source/blender/python/generic/py_capi_utils.c | 79 |
1 files changed, 18 insertions, 61 deletions
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 81aea8571f8..b7e67ec5a93 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -208,77 +208,34 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) return item; } -/* returns the exception string as a new PyUnicode object, depends on external StringIO module */ +/* returns the exception string as a new PyUnicode object, depends on external traceback module */ 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")) ) { + PyObject *traceback_mod= NULL; + PyObject *format_tb_func= NULL; + PyObject *ret= NULL; + + if(! (traceback_mod= PyImport_ImportModule("traceback")) ) { goto error_cleanup; } - else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) { + else if (! (format_tb_func= PyObject_GetAttrString(traceback_mod, "format_exc"))) { goto error_cleanup; } - else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) { - goto error_cleanup; + + ret= PyObject_CallObject(format_tb_func, NULL); + + if(ret == Py_None) { + Py_DECREF(ret); + ret= NULL; } - - 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; -} + Py_XDECREF(traceback_mod); + Py_XDECREF(format_tb_func); + return ret; +} /* string conversion, escape non-unicode chars, coerce must be set to NULL */ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) |