int BPY_string_exec(bContext *C, const char *expr) { PyGILState_STATE gilstate; PyObject *main_mod = NULL; PyObject *py_dict, *retval; int error_ret = 0; Main *bmain_back; /* XXX, quick fix for release (Copy Settings crash), needs further investigation */ if (!expr) return -1; if (expr[0] == '\0') { return error_ret; } bpy_context_set(C, &gilstate); PyC_MainModule_Backup(&main_mod); py_dict = PyC_DefaultNameSpace("<blender string>"); bmain_back = bpy_import_main_get(); bpy_import_main_set(CTX_data_main(C)); retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); bpy_import_main_set(bmain_back); if (retval == NULL) { error_ret = -1; BPy_errors_to_report(CTX_wm_reports(C)); } else { Py_DECREF(retval); } PyC_MainModule_Restore(main_mod); bpy_context_clear(C, &gilstate); return error_ret; }
/* return -1 on error, else 0 */ int BPY_button_exec(bContext *C, const char *expr, double *value, const short verbose) { PyGILState_STATE gilstate; PyObject *py_dict, *mod, *retval; int error_ret = 0; PyObject *main_mod = NULL; if (!value || !expr) return -1; if (expr[0] == '\0') { *value = 0.0; return error_ret; } bpy_context_set(C, &gilstate); PyC_MainModule_Backup(&main_mod); py_dict = PyC_DefaultNameSpace("<blender button>"); mod = PyImport_ImportModule("math"); if (mod) { PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - don't overwrite existing values */ Py_DECREF(mod); } else { /* highly unlikely but possibly */ PyErr_Print(); PyErr_Clear(); } retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); if (retval == NULL) { error_ret = -1; } else { double val; if (PyTuple_Check(retval)) { /* Users my have typed in 10km, 2m * add up all values */ int i; val = 0.0; for (i = 0; i < PyTuple_GET_SIZE(retval); i++) { val += PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i)); } } else { val = PyFloat_AsDouble(retval); } Py_DECREF(retval); if (val == -1 && PyErr_Occurred()) { error_ret = -1; } else if (!finite(val)) { *value = 0.0; } else { *value = val; } } if (error_ret) { if (verbose) { BPy_errors_to_report(CTX_wm_reports(C)); } else { PyErr_Clear(); } } PyC_MainModule_Backup(&main_mod); bpy_context_clear(C, &gilstate); return error_ret; }
static bool python_script_exec( bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump) { Main *bmain_old = CTX_data_main(C); PyObject *main_mod = NULL; PyObject *py_dict = NULL, *py_result = NULL; PyGILState_STATE gilstate; BLI_assert(fn || text); if (fn == NULL && text == NULL) { return 0; } bpy_context_set(C, &gilstate); PyC_MainModule_Backup(&main_mod); if (text) { char fn_dummy[FILE_MAXDIR]; bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ char *buf; PyObject *fn_dummy_py; fn_dummy_py = PyC_UnicodeFromByte(fn_dummy); buf = txt_to_buf(text); text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1); MEM_freeN(buf); Py_DECREF(fn_dummy_py); if (PyErr_Occurred()) { if (do_jump) { python_script_error_jump_text(text); } BPY_text_free_code(text); } } if (text->compiled) { py_dict = PyC_DefaultNameSpace(fn_dummy); py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); } } else { FILE *fp = BLI_fopen(fn, "r"); if (fp) { py_dict = PyC_DefaultNameSpace(fn); #ifdef _WIN32 /* Previously we used PyRun_File to run directly the code on a FILE * object, but as written in the Python/C API Ref Manual, chapter 2, * 'FILE structs for different C libraries can be different and * incompatible'. * So now we load the script file data to a buffer */ { const char *pystring = "ns = globals().copy()\n" "with open(__file__, 'rb') as f: exec(compile(f.read(), __file__, 'exec'), ns)"; fclose(fp); py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); } #else py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); fclose(fp); #endif } else { PyErr_Format(PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno)); py_result = NULL; } } if (!py_result) { if (text) { if (do_jump) { /* ensure text is valid before use, the script may have freed its self */ Main *bmain_new = CTX_data_main(C); if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->text, text) != -1)) { python_script_error_jump_text(text); } } } BPy_errors_to_report(reports); } else { Py_DECREF(py_result); } if (py_dict) { #ifdef PYMODULE_CLEAR_WORKAROUND PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__"); PyObject *dict_back = mmod->md_dict; /* freeing the module will clear the namespace, * gives problems running classes defined in this namespace being used later. */ mmod->md_dict = NULL; Py_DECREF(dict_back); #endif #undef PYMODULE_CLEAR_WORKAROUND } PyC_MainModule_Restore(main_mod); bpy_context_clear(C, &gilstate); return (py_result != NULL); }
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const short do_jump) { PyObject *main_mod = NULL; PyObject *py_dict = NULL, *py_result = NULL; PyGILState_STATE gilstate; BLI_assert(fn || text); if (fn == NULL && text == NULL) { return 0; } bpy_context_set(C, &gilstate); PyC_MainModule_Backup(&main_mod); if (text) { char fn_dummy[FILE_MAXDIR]; bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ char *buf = txt_to_buf(text); text->compiled = Py_CompileString(buf, fn_dummy, Py_file_input); MEM_freeN(buf); if (PyErr_Occurred()) { if (do_jump) { python_script_error_jump_text(text); } BPY_text_free_code(text); } } if (text->compiled) { py_dict = PyC_DefaultNameSpace(fn_dummy); py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); } } else { FILE *fp = BLI_fopen(fn, "r"); if (fp) { py_dict = PyC_DefaultNameSpace(fn); #ifdef _WIN32 /* Previously we used PyRun_File to run directly the code on a FILE * object, but as written in the Python/C API Ref Manual, chapter 2, * 'FILE structs for different C libraries can be different and * incompatible'. * So now we load the script file data to a buffer */ { char *pystring; fclose(fp); pystring = MEM_mallocN(strlen(fn) + 32, "pystring"); pystring[0] = '\0'; sprintf(pystring, "exec(open(r'%s').read())", fn); py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); MEM_freeN(pystring); } #else py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); fclose(fp); #endif } else { PyErr_Format(PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno)); py_result = NULL; } } if (!py_result) { if (text) { if (do_jump) { python_script_error_jump_text(text); } } BPy_errors_to_report(reports); } else { Py_DECREF(py_result); } if (py_dict) { #ifdef PYMODULE_CLEAR_WORKAROUND PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__"); PyObject *dict_back = mmod->md_dict; /* freeing the module will clear the namespace, * gives problems running classes defined in this namespace being used later. */ mmod->md_dict = NULL; Py_DECREF(dict_back); #endif #undef PYMODULE_CLEAR_WORKAROUND } PyC_MainModule_Restore(main_mod); bpy_context_clear(C, &gilstate); return (py_result != NULL); }
/* Would be nice if python had this built in */ void PyC_RunQuicky(const char *filepath, int n, ...) { FILE *fp= fopen(filepath, "r"); if(fp) { PyGILState_STATE gilstate= PyGILState_Ensure(); va_list vargs; int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2)); int i; PyObject *py_dict = PyC_DefaultNameSpace(filepath); PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */ PyObject *py_result, *ret; PyObject *struct_mod= PyImport_ImportModule("struct"); PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */ PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */ PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */ Py_DECREF(struct_mod); va_start(vargs, n); for (i=0; i * 2<n; i++) { char *format = va_arg(vargs, char *); void *ptr = va_arg(vargs, void *); ret= PyObject_CallFunction(calcsize, (char *)"s", format); if(ret) { sizes[i]= PyLong_AsSsize_t(ret); Py_DECREF(ret); ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]); } if(ret == NULL) { printf("PyC_InlineRun error, line:%d\n", __LINE__); PyErr_Print(); PyErr_Clear(); PyList_SET_ITEM(values, i, Py_None); /* hold user */ Py_INCREF(Py_None); sizes[i]= 0; } else { if(PyTuple_GET_SIZE(ret) == 1) { /* convenience, convert single tuples into single values */ PyObject *tmp= PyTuple_GET_ITEM(ret, 0); Py_INCREF(tmp); Py_DECREF(ret); ret = tmp; } PyList_SET_ITEM(values, i, ret); /* hold user */ } } va_end(vargs); /* set the value so we can access it */ PyDict_SetItemString(py_dict, "values", values); py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict); fclose(fp); if(py_result) { /* we could skip this but then only slice assignment would work * better not be so strict */ values= PyDict_GetItemString(py_dict, "values"); if(values && PyList_Check(values)) { /* dont use the result */ Py_DECREF(py_result); py_result= NULL; /* now get the values back */ va_start(vargs, n); for (i=0; i*2 <n; i++) { char *format = va_arg(vargs, char *); void *ptr = va_arg(vargs, void *); PyObject *item; PyObject *item_new; /* prepend the string formatting and remake the tuple */ item= PyList_GET_ITEM(values, i); if(PyTuple_CheckExact(item)) { int ofs= PyTuple_GET_SIZE(item); item_new= PyTuple_New(ofs + 1); while(ofs--) { PyObject *member= PyTuple_GET_ITEM(item, ofs); PyTuple_SET_ITEM(item_new, ofs + 1, member); Py_INCREF(member); } PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format)); } else { item_new= Py_BuildValue("sO", format, item); } ret = PyObject_Call(pack, item_new, NULL); if(ret) { /* copy the bytes back into memory */ memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]); Py_DECREF(ret); } else { printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__); PyC_ObSpit("failed converting:", item_new); PyErr_Print(); PyErr_Clear(); } Py_DECREF(item_new); } va_end(vargs); } else { printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__); } }