Blender  V2.59
py_capi_utils.c
Go to the documentation of this file.
00001 /*
00002  * $Id: py_capi_utils.c 38265 2011-07-09 17:41:39Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021 */
00022 
00028 #include <Python.h>
00029 #include <frameobject.h>
00030 
00031 #include "py_capi_utils.h"
00032 
00033 #include "BKE_font.h" /* only for utf8towchar, should replace with py funcs but too late in release now */
00034 
00035 #ifdef _WIN32 /* BLI_setenv */
00036 #include "BLI_path_util.h"
00037 #endif
00038 
00039 /* array utility function */
00040 int PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix)
00041 {
00042         PyObject *value_fast;
00043         int value_len;
00044         int i;
00045 
00046         if(!(value_fast=PySequence_Fast(value, error_prefix))) {
00047                 return -1;
00048         }
00049 
00050         value_len= PySequence_Fast_GET_SIZE(value_fast);
00051 
00052         if(value_len != length) {
00053                 Py_DECREF(value);
00054                 PyErr_Format(PyExc_TypeError,
00055                              "%.200s: invalid sequence length. expected %d, got %d",
00056                              error_prefix, length, value_len);
00057                 return -1;
00058         }
00059 
00060         /* for each type */
00061         if(type == &PyFloat_Type) {
00062                 if(is_double) {
00063                         double *array_double= array;
00064                         for(i=0; i<length; i++) {
00065                                 array_double[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
00066                         }
00067                 }
00068                 else {
00069                         float *array_float= array;
00070                         for(i=0; i<length; i++) {
00071                                 array_float[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
00072                         }
00073                 }
00074         }
00075         else if(type == &PyLong_Type) {
00076                 /* could use is_double for 'long int' but no use now */
00077                 int *array_int= array;
00078                 for(i=0; i<length; i++) {
00079                         array_int[i]= PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i));
00080                 }
00081         }
00082         else if(type == &PyBool_Type) {
00083                 int *array_bool= array;
00084                 for(i=0; i<length; i++) {
00085                         array_bool[i]= (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
00086                 }
00087         }
00088         else {
00089                 Py_DECREF(value_fast);
00090                 PyErr_Format(PyExc_TypeError,
00091                              "%s: internal error %s is invalid",
00092                              error_prefix, type->tp_name);
00093                 return -1;
00094         }
00095 
00096         Py_DECREF(value_fast);
00097 
00098         if(PyErr_Occurred()) {
00099                 PyErr_Format(PyExc_TypeError,
00100                              "%s: one or more items could not be used as a %s",
00101                              error_prefix, type->tp_name);
00102                 return -1;
00103         }
00104 
00105         return 0;
00106 }
00107 
00108 
00109 /* for debugging */
00110 void PyC_ObSpit(const char *name, PyObject *var) {
00111         fprintf(stderr, "<%s> : ", name);
00112         if (var==NULL) {
00113                 fprintf(stderr, "<NIL>");
00114         }
00115         else {
00116                 PyObject_Print(var, stderr, 0);
00117                 fprintf(stderr, " ref:%d ", (int)var->ob_refcnt);
00118                 fprintf(stderr, " ptr:%p", (void *)var);
00119                 
00120                 fprintf(stderr, " type:");
00121                 if(Py_TYPE(var))
00122                         fprintf(stderr, "%s", Py_TYPE(var)->tp_name);
00123                 else
00124                         fprintf(stderr, "<NIL>");
00125         }
00126         fprintf(stderr, "\n");
00127 }
00128 
00129 void PyC_LineSpit(void) {
00130 
00131         const char *filename;
00132         int lineno;
00133 
00134         /* Note, allow calling from outside python (RNA) */
00135         if(!PYC_INTERPRETER_ACTIVE) {
00136                 fprintf(stderr, "python line lookup failed, interpreter inactive\n");
00137                 return;
00138         }
00139 
00140         PyErr_Clear();
00141         PyC_FileAndNum(&filename, &lineno);
00142         
00143         fprintf(stderr, "%s:%d\n", filename, lineno);
00144 }
00145 
00146 void PyC_FileAndNum(const char **filename, int *lineno)
00147 {
00148         PyFrameObject *frame;
00149         
00150         if (filename)   *filename= NULL;
00151         if (lineno)             *lineno = -1;
00152 
00153         if (!(frame= PyThreadState_GET()->frame)) {
00154                 return;
00155         }
00156 
00157         /* when executing a script */
00158         if (filename) {
00159                 *filename = _PyUnicode_AsString(frame->f_code->co_filename);
00160         }
00161 
00162         /* when executing a module */
00163         if(filename && *filename == NULL) {
00164                 /* try an alternative method to get the filename - module based
00165                  * references below are all borrowed (double checked) */
00166                 PyObject *mod_name= PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
00167                 if(mod_name) {
00168                         PyObject *mod= PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
00169                         if(mod) {
00170                                 *filename= PyModule_GetFilename(mod);
00171                         }
00172 
00173                         /* unlikely, fallback */
00174                         if(*filename == NULL) {
00175                                 *filename= _PyUnicode_AsString(mod_name);
00176                         }
00177                 }
00178         }
00179 
00180         if (lineno) {
00181                 *lineno = PyFrame_GetLineNumber(frame);
00182         }
00183 }
00184 
00185 /* Would be nice if python had this built in */
00186 PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
00187 {
00188         Py_ssize_t i;
00189         PyObject *item= o;
00190         char *attr;
00191         
00192         va_list vargs;
00193 
00194         va_start(vargs, n);
00195         for (i=0; i<n; i++) {
00196                 attr = va_arg(vargs, char *);
00197                 item = PyObject_GetAttrString(item, attr);
00198                 
00199                 if (item) 
00200                         Py_DECREF(item);
00201                 else /* python will set the error value here */
00202                         break;
00203                 
00204         }
00205         va_end(vargs);
00206         
00207         Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
00208         return item;
00209 }
00210 
00211 /* returns the exception string as a new PyUnicode object, depends on external StringIO module */
00212 PyObject *PyC_ExceptionBuffer(void)
00213 {
00214         PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
00215         PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
00216         PyObject *string_io = NULL;
00217         PyObject *string_io_buf = NULL;
00218         PyObject *string_io_mod= NULL;
00219         PyObject *string_io_getvalue= NULL;
00220         
00221         PyObject *error_type, *error_value, *error_traceback;
00222         
00223         if (!PyErr_Occurred())
00224                 return NULL;
00225         
00226         PyErr_Fetch(&error_type, &error_value, &error_traceback);
00227         
00228         PyErr_Clear();
00229         
00230         /* import io
00231          * string_io = io.StringIO()
00232          */
00233         
00234         if(! (string_io_mod= PyImport_ImportModule("io")) ) {
00235                 goto error_cleanup;
00236         }
00237         else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) {
00238                 goto error_cleanup;
00239         }
00240         else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
00241                 goto error_cleanup;
00242         }
00243         
00244         Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced.
00245         Py_INCREF(stderr_backup);
00246         
00247         PySys_SetObject("stdout", string_io); // both of these are free'd when restoring
00248         PySys_SetObject("stderr", string_io);
00249         
00250         PyErr_Restore(error_type, error_value, error_traceback);
00251         PyErr_Print(); /* print the error */
00252         PyErr_Clear();
00253         
00254         string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
00255         
00256         PySys_SetObject("stdout", stdout_backup);
00257         PySys_SetObject("stderr", stderr_backup);
00258         
00259         Py_DECREF(stdout_backup); /* now sys owns the ref again */
00260         Py_DECREF(stderr_backup);
00261         
00262         Py_DECREF(string_io_mod);
00263         Py_DECREF(string_io_getvalue);
00264         Py_DECREF(string_io); /* free the original reference */
00265         
00266         PyErr_Clear();
00267         return string_io_buf;
00268         
00269         
00270 error_cleanup:
00271         /* could not import the module so print the error and close */
00272         Py_XDECREF(string_io_mod);
00273         Py_XDECREF(string_io);
00274         
00275         PyErr_Restore(error_type, error_value, error_traceback);
00276         PyErr_Print(); /* print the error */
00277         PyErr_Clear();
00278         
00279         return NULL;
00280 }
00281 
00282 
00283 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
00284 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
00285 {
00286         char *result;
00287 
00288         result= _PyUnicode_AsString(py_str);
00289 
00290         if(result) {
00291                 /* 99% of the time this is enough but we better support non unicode
00292                  * chars since blender doesnt limit this */
00293                 return result;
00294         }
00295         else if(PyBytes_Check(py_str)) {
00296                 PyErr_Clear();
00297                 return PyBytes_AS_STRING(py_str);
00298         }
00299         else {
00300                 return PyBytes_AS_STRING((*coerce= PyUnicode_EncodeFSDefault(py_str)));
00301         }
00302 }
00303 
00304 PyObject *PyC_UnicodeFromByte(const char *str)
00305 {
00306         PyObject *result= PyUnicode_FromString(str);
00307         if(result) {
00308                 /* 99% of the time this is enough but we better support non unicode
00309                  * chars since blender doesnt limit this */
00310                 return result;
00311         }
00312         else {
00313                 PyErr_Clear();
00314                 /* this means paths will always be accessible once converted, on all OS's */
00315                 result= PyUnicode_DecodeFSDefault(str);
00316                 return result;
00317         }
00318 }
00319 
00320 /*****************************************************************************
00321 * Description: This function creates a new Python dictionary object.
00322 * note: dict is owned by sys.modules["__main__"] module, reference is borrowed
00323 * note: important we use the dict from __main__, this is what python expects
00324   for 'pickle' to work as well as strings like this...
00325  >> foo = 10
00326  >> print(__import__("__main__").foo)
00327 *
00328 * note: this overwrites __main__ which gives problems with nested calles.
00329 * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
00330 * any chance that python is in the call stack.
00331 *****************************************************************************/
00332 PyObject *PyC_DefaultNameSpace(const char *filename)
00333 {
00334         PyInterpreterState *interp= PyThreadState_GET()->interp;
00335         PyObject *mod_main= PyModule_New("__main__");   
00336         PyDict_SetItemString(interp->modules, "__main__", mod_main);
00337         Py_DECREF(mod_main); /* sys.modules owns now */
00338         PyModule_AddStringConstant(mod_main, "__name__", "__main__");
00339         if(filename)
00340                 PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */
00341         PyModule_AddObject(mod_main, "__builtins__", interp->builtins);
00342         Py_INCREF(interp->builtins); /* AddObject steals a reference */
00343         return PyModule_GetDict(mod_main);
00344 }
00345 
00346 /* restore MUST be called after this */
00347 void PyC_MainModule_Backup(PyObject **main_mod)
00348 {
00349         PyInterpreterState *interp= PyThreadState_GET()->interp;
00350         *main_mod= PyDict_GetItemString(interp->modules, "__main__");
00351         Py_XINCREF(*main_mod); /* dont free */
00352 }
00353 
00354 void PyC_MainModule_Restore(PyObject *main_mod)
00355 {
00356         PyInterpreterState *interp= PyThreadState_GET()->interp;
00357         PyDict_SetItemString(interp->modules, "__main__", main_mod);
00358         Py_XDECREF(main_mod);
00359 }
00360 
00361 /* must be called before Py_Initialize, expects output of BLI_get_folder(BLENDER_PYTHON, NULL) */
00362 void PyC_SetHomePath(const char *py_path_bundle)
00363 {
00364         if(py_path_bundle==NULL) {
00365                 /* Common enough to have bundled *nix python but complain on OSX/Win */
00366 #if defined(__APPLE__) || defined(_WIN32)
00367                 fprintf(stderr, "Warning! bundled python not found and is expected on this platform. (if you built with CMake: 'install' target may have not been built)\n");
00368 #endif
00369                 return;
00370         }
00371         /* set the environment path */
00372         printf("found bundled python: %s\n", py_path_bundle);
00373 
00374 #ifdef __APPLE__
00375         /* OSX allow file/directory names to contain : character (represented as / in the Finder)
00376          but current Python lib (release 3.1.1) doesn't handle these correctly */
00377         if(strchr(py_path_bundle, ':'))
00378                 printf("Warning : Blender application is located in a path containing : or / chars\
00379                            \nThis may make python import function fail\n");
00380 #endif
00381 
00382 #ifdef _WIN32
00383         /* cmake/MSVC debug build crashes without this, why only
00384            in this case is unknown.. */
00385         {
00386                 BLI_setenv("PYTHONPATH", py_path_bundle);
00387         }
00388 #endif
00389 
00390         {
00391                 static wchar_t py_path_bundle_wchar[1024];
00392 
00393                 /* cant use this, on linux gives bug: #23018, TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 22008 */
00394                 /* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */
00395 
00396                 utf8towchar(py_path_bundle_wchar, py_path_bundle);
00397 
00398                 Py_SetPythonHome(py_path_bundle_wchar);
00399                 // printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
00400         }
00401 }
00402 
00403 /* Would be nice if python had this built in */
00404 void PyC_RunQuicky(const char *filepath, int n, ...)
00405 {
00406         FILE *fp= fopen(filepath, "r");
00407 
00408         if(fp) {
00409                 PyGILState_STATE gilstate= PyGILState_Ensure();
00410 
00411                 va_list vargs;  
00412 
00413                 int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2));
00414                 int i;
00415 
00416                 PyObject *py_dict = PyC_DefaultNameSpace(filepath);
00417                 PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */
00418 
00419                 PyObject *py_result, *ret;
00420 
00421                 PyObject *struct_mod= PyImport_ImportModule("struct");
00422                 PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
00423                 PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */
00424                 PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */
00425 
00426                 Py_DECREF(struct_mod);
00427 
00428                 va_start(vargs, n);
00429                 for (i=0; i * 2<n; i++) {
00430                         char *format = va_arg(vargs, char *);
00431                         void *ptr = va_arg(vargs, void *);
00432 
00433                         ret= PyObject_CallFunction(calcsize, (char *)"s", format);
00434 
00435                         if(ret) {
00436                                 sizes[i]= PyLong_AsSsize_t(ret);
00437                                 Py_DECREF(ret);
00438                                 ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]);
00439                         }
00440 
00441                         if(ret == NULL) {
00442                                 printf("PyC_InlineRun error, line:%d\n", __LINE__);
00443                                 PyErr_Print();
00444                                 PyErr_Clear();
00445 
00446                                 PyList_SET_ITEM(values, i, Py_None); /* hold user */
00447                                 Py_INCREF(Py_None);
00448 
00449                                 sizes[i]= 0;
00450                         }
00451                         else {
00452                                 if(PyTuple_GET_SIZE(ret) == 1) {
00453                                         /* convenience, convert single tuples into single values */
00454                                         PyObject *tmp= PyTuple_GET_ITEM(ret, 0);
00455                                         Py_INCREF(tmp);
00456                                         Py_DECREF(ret);
00457                                         ret = tmp;
00458                                 }
00459 
00460                                 PyList_SET_ITEM(values, i, ret); /* hold user */
00461                         }
00462                 }
00463                 va_end(vargs);
00464                 
00465                 /* set the value so we can access it */
00466                 PyDict_SetItemString(py_dict, "values", values);
00467 
00468                 py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
00469 
00470                 fclose(fp);
00471 
00472                 if(py_result) {
00473 
00474                         /* we could skip this but then only slice assignment would work
00475                          * better not be so strict */
00476                         values= PyDict_GetItemString(py_dict, "values");
00477 
00478                         if(values && PyList_Check(values)) {
00479 
00480                                 /* dont use the result */
00481                                 Py_DECREF(py_result);
00482                                 py_result= NULL;
00483 
00484                                 /* now get the values back */
00485                                 va_start(vargs, n);
00486                                 for (i=0; i*2 <n; i++) {
00487                                         char *format = va_arg(vargs, char *);
00488                                         void *ptr = va_arg(vargs, void *);
00489                                         
00490                                         PyObject *item;
00491                                         PyObject *item_new;
00492                                         /* prepend the string formatting and remake the tuple */
00493                                         item= PyList_GET_ITEM(values, i);
00494                                         if(PyTuple_CheckExact(item)) {
00495                                                 int ofs= PyTuple_GET_SIZE(item);
00496                                                 item_new= PyTuple_New(ofs + 1);
00497                                                 while(ofs--) {
00498                                                         PyObject *member= PyTuple_GET_ITEM(item, ofs);
00499                                                         PyTuple_SET_ITEM(item_new, ofs + 1, member);
00500                                                         Py_INCREF(member);
00501                                                 }
00502 
00503                                                 PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
00504                                         }
00505                                         else {
00506                                                 item_new= Py_BuildValue("sO", format, item);
00507                                         }
00508 
00509                                         ret = PyObject_Call(pack, item_new, NULL);
00510 
00511                                         if(ret) {
00512                                                 /* copy the bytes back into memory */
00513                                                 memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
00514                                                 Py_DECREF(ret);
00515                                         }
00516                                         else {
00517                                                 printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__);
00518                                                 PyC_ObSpit("failed converting:", item_new);
00519                                                 PyErr_Print();
00520                                                 PyErr_Clear();
00521                                         }
00522 
00523                                         Py_DECREF(item_new);
00524                                 }
00525                                 va_end(vargs);
00526                         }
00527                         else {
00528                                 printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__);
00529                         }
00530                 }
00531                 else {
00532                         printf("PyC_InlineRun error line:%d\n", __LINE__);
00533                         PyErr_Print();
00534                         PyErr_Clear();
00535                 }
00536 
00537                 Py_DECREF(calcsize);
00538                 Py_DECREF(pack);
00539                 Py_DECREF(unpack);
00540 
00541                 PyMem_FREE(sizes);
00542 
00543                 PyGILState_Release(gilstate);
00544         }
00545 }