|
Blender
V2.59
|
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 }