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:
Diffstat (limited to 'source/blender/python/generic/py_capi_utils.c')
-rw-r--r--source/blender/python/generic/py_capi_utils.c149
1 files changed, 87 insertions, 62 deletions
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index ec774f44075..b7e67ec5a93 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -36,7 +36,75 @@
#include "BLI_path_util.h"
#endif
-#define PYC_INTERPRETER_ACTIVE (((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL)
+/* array utility function */
+int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix)
+{
+ PyObject *value_fast;
+ int value_len;
+ int i;
+
+ if(!(value_fast=PySequence_Fast(value, error_prefix))) {
+ return -1;
+ }
+
+ value_len= PySequence_Fast_GET_SIZE(value_fast);
+
+ if(value_len != length) {
+ Py_DECREF(value);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: invalid sequence length. expected %d, got %d",
+ error_prefix, length, value_len);
+ return -1;
+ }
+
+ /* for each type */
+ if(type == &PyFloat_Type) {
+ if(is_double) {
+ double *array_double= array;
+ for(i=0; i<length; i++) {
+ array_double[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
+ }
+ }
+ else {
+ float *array_float= array;
+ for(i=0; i<length; i++) {
+ array_float[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
+ }
+ }
+ }
+ else if(type == &PyLong_Type) {
+ /* could use is_double for 'long int' but no use now */
+ int *array_int= array;
+ for(i=0; i<length; i++) {
+ array_int[i]= PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i));
+ }
+ }
+ else if(type == &PyBool_Type) {
+ int *array_bool= array;
+ for(i=0; i<length; i++) {
+ array_bool[i]= (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
+ }
+ }
+ else {
+ Py_DECREF(value_fast);
+ PyErr_Format(PyExc_TypeError,
+ "%s: internal error %s is invalid",
+ error_prefix, type->tp_name);
+ return -1;
+ }
+
+ Py_DECREF(value_fast);
+
+ if(PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "%s: one or more items could not be used as a %s",
+ error_prefix, type->tp_name);
+ return -1;
+ }
+
+ return 0;
+}
+
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var) {
@@ -140,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)