// PyDoc_STRVAR(bpy_user_resource_doc[] = // now in bpy/utils.py static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { const char *type; const char *subdir = NULL; int folder_id; static const char *kwlist[] = {"type", "subdir", NULL}; const char *path; if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", (char **)kwlist, &type, &subdir)) return NULL; /* stupid string compare */ if (STREQ(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES; else if (STREQ(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG; else if (STREQ(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS; else if (STREQ(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE; else { PyErr_SetString(PyExc_ValueError, "invalid resource argument"); return NULL; } /* same logic as BKE_appdir_folder_id_create(), but best leave it up to the script author to create */ path = BKE_appdir_folder_id(folder_id, subdir); if (!path) path = BKE_appdir_folder_id_user_notest(folder_id, subdir); return PyC_UnicodeFromByte(path ? path : ""); }
bool bpy_text_compile(Text *text) { char fn_dummy[FILE_MAX]; PyObject *fn_dummy_py; char *buf; bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); /* if previously compiled, free the object */ free_compiled_text(text); 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()) { PyErr_Print(); PyErr_Clear(); PySys_SetObject("last_traceback", NULL); free_compiled_text(text); return false; } else { return true; } }
static PyObject *bpy_script_paths(PyObject *UNUSED(self)) { PyObject *ret = PyTuple_New(2); PyObject *item; const char *path; path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, NULL); item = PyC_UnicodeFromByte(path ? path : ""); BLI_assert(item != NULL); PyTuple_SET_ITEM(ret, 0, item); path = BKE_appdir_folder_id(BLENDER_USER_SCRIPTS, NULL); item = PyC_UnicodeFromByte(path ? path : ""); BLI_assert(item != NULL); PyTuple_SET_ITEM(ret, 1, item); return ret; }
PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop ) { switch ( prop->type ) { case IDP_STRING: #ifdef USE_STRING_COERCE return PyC_UnicodeFromByte(prop->data.pointer); #else return PyUnicode_FromString(prop->data.pointer); #endif case IDP_INT: return PyLong_FromLong( (long)prop->data.val ); case IDP_FLOAT: return PyFloat_FromDouble( (double)(*(float*)(&prop->data.val)) ); case IDP_DOUBLE: return PyFloat_FromDouble( (*(double*)(&prop->data.val)) ); case IDP_GROUP: /*blegh*/ { BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &IDGroup_Type); group->id = id; group->prop = prop; return (PyObject*) group; } case IDP_ARRAY: { BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &IDArray_Type); array->id = id; array->prop = prop; return (PyObject*) array; } case IDP_IDPARRAY: /* this could be better a internal type */ { PyObject *seq = PyList_New(prop->len), *wrap; IDProperty *array= IDP_IDPArray(prop); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_IDPARRAY: PyList_New(%d) failed", prop->len); return NULL; } for (i=0; i<prop->len; i++) { wrap= BPy_IDGroup_WrapData(id, array++); if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ return NULL; PyList_SET_ITEM(seq, i, wrap); } return seq; } /* case IDP_IDPARRAY: TODO */ } Py_RETURN_NONE; }
static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { const char *type; int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100; static const char *kwlist[] = {"type", "major", "minor", NULL}; int folder_id; const char *path; if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ii:resource_path", (char **)kwlist, &type, &major, &minor)) return NULL; /* stupid string compare */ if (STREQ(type, "USER")) folder_id = BLENDER_RESOURCE_PATH_USER; else if (STREQ(type, "LOCAL")) folder_id = BLENDER_RESOURCE_PATH_LOCAL; else if (STREQ(type, "SYSTEM")) folder_id = BLENDER_RESOURCE_PATH_SYSTEM; else { PyErr_SetString(PyExc_ValueError, "invalid resource argument"); return NULL; } path = BKE_appdir_folder_id_version(folder_id, (major * 100) + minor, false); return PyC_UnicodeFromByte(path ? path : ""); }
/* call BPY_context_set first */ void BPY_python_start(int argc, const char **argv) { #ifndef WITH_PYTHON_MODULE PyThreadState *py_tstate = NULL; /* not essential but nice to set our name */ static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ BLI_strncpy_wchar_from_utf8(program_path_wchar, BLI_program_path(), sizeof(program_path_wchar) / sizeof(wchar_t)); Py_SetProgramName(program_path_wchar); /* must run before python initializes */ PyImport_ExtendInittab(bpy_internal_modules); /* allow to use our own included python */ PyC_SetHomePath(BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL)); /* without this the sys.stdout may be set to 'ascii' * (it is on my system at least), where printing unicode values will raise * an error, this is highly annoying, another stumbling block for devs, * so use a more relaxed error handler and enforce utf-8 since the rest of * blender is utf-8 too - campbell */ BLI_setenv("PYTHONIOENCODING", "utf-8:surrogateescape"); /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to * parse from the 'sysconfig' module which is used by 'site', * so for now disable site. alternatively we could copy the file. */ Py_NoSiteFlag = 1; Py_Initialize(); // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal /* sigh, why do python guys not have a (char **) version anymore? */ { int i; PyObject *py_argv = PyList_New(argc); for (i = 0; i < argc; i++) { /* should fix bug #20021 - utf path name problems, by replacing * PyUnicode_FromString, with this one */ PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); } PySys_SetObject("argv", py_argv); Py_DECREF(py_argv); } /* Initialize thread support (also acquires lock) */ PyEval_InitThreads(); #else (void)argc; (void)argv; /* must run before python initializes */ PyImport_ExtendInittab(bpy_internal_modules); #endif bpy_intern_string_init(); /* bpy.* and lets us import it */ BPy_init_modules(); bpy_import_init(PyEval_GetBuiltins()); pyrna_alloc_types(); #ifndef WITH_PYTHON_MODULE /* py module runs atexit when bpy is freed */ BPY_atexit_register(); /* this can init any time */ py_tstate = PyGILState_GetThisThreadState(); PyEval_ReleaseThread(py_tstate); #endif }
static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) { switch (prop->type) { case IDP_STRING: #ifdef USE_STRING_COERCE return PyC_UnicodeFromByte(prop->data.pointer); #else return PyUnicode_FromString(prop->data.pointer); #endif break; case IDP_FLOAT: return PyFloat_FromDouble(*((float*)&prop->data.val)); break; case IDP_DOUBLE: return PyFloat_FromDouble(*((double*)&prop->data.val)); break; case IDP_INT: return PyLong_FromSsize_t( prop->data.val ); break; case IDP_ARRAY: { PyObject *seq = PyList_New(prop->len); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_ARRAY: PyList_New(%d) failed", prop->len); return NULL; } for (i=0; i<prop->len; i++) { if (prop->subtype == IDP_FLOAT) { PyList_SET_ITEM(seq, i, PyFloat_FromDouble(((float*)prop->data.pointer)[i])); } else if (prop->subtype == IDP_DOUBLE) { PyList_SET_ITEM(seq, i, PyFloat_FromDouble(((double*)prop->data.pointer)[i])); } else { PyList_SET_ITEM(seq, i, PyLong_FromLong(((int*)prop->data.pointer)[i])); } } return seq; } case IDP_IDPARRAY: { PyObject *seq = PyList_New(prop->len), *wrap; IDProperty *array= IDP_IDPArray(prop); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_IDPARRAY: PyList_New(%d) failed", prop->len); return NULL; } for (i=0; i<prop->len; i++) { wrap= BPy_IDGroup_MapDataToPy(array++); if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ return NULL; PyList_SET_ITEM(seq, i, wrap); } return seq; } case IDP_GROUP: { PyObject *dict = PyDict_New(), *wrap; IDProperty *loop; for (loop=prop->data.group.first; loop; loop=loop->next) { wrap = BPy_IDGroup_MapDataToPy(loop); if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ return NULL; PyDict_SetItemString(dict, loop->name, wrap); } return dict; } } PyErr_Format(PyExc_RuntimeError, "eek!! '%s' property exists with a bad type code '%d' !!!", prop->name, prop->type); return NULL; }
static bool bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src) { PyList_APPEND((PyObject *)userdata, PyC_UnicodeFromByte(path_src)); return false; /* never edits the path */ }
static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure)) { extern char btempdir[]; return PyC_UnicodeFromByte(btempdir); }
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); }
/* call BPY_context_set first */ void BPY_python_start(int argc, const char **argv) { #ifndef WITH_PYTHON_MODULE PyThreadState *py_tstate = NULL; const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); /* not essential but nice to set our name */ static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar)); Py_SetProgramName(program_path_wchar); /* must run before python initializes */ PyImport_ExtendInittab(bpy_internal_modules); /* allow to use our own included python */ PyC_SetHomePath(py_path_bundle); /* without this the sys.stdout may be set to 'ascii' * (it is on my system at least), where printing unicode values will raise * an error, this is highly annoying, another stumbling block for devs, * so use a more relaxed error handler and enforce utf-8 since the rest of * blender is utf-8 too - campbell */ Py_SetStandardStreamEncoding("utf-8", "surrogateescape"); /* Update, Py3.3 resolves attempting to parse non-existing header */ #if 0 /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to * parse from the 'sysconfig' module which is used by 'site', * so for now disable site. alternatively we could copy the file. */ if (py_path_bundle) { Py_NoSiteFlag = 1; } #endif Py_FrozenFlag = 1; Py_Initialize(); // PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */ /* sigh, why do python guys not have a (char **) version anymore? */ { int i; PyObject *py_argv = PyList_New(argc); for (i = 0; i < argc; i++) { /* should fix bug #20021 - utf path name problems, by replacing * PyUnicode_FromString, with this one */ PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); } PySys_SetObject("argv", py_argv); Py_DECREF(py_argv); } /* Initialize thread support (also acquires lock) */ PyEval_InitThreads(); #else (void)argc; (void)argv; /* must run before python initializes */ /* broken in py3.3, load explicitly below */ // PyImport_ExtendInittab(bpy_internal_modules); #endif bpy_intern_string_init(); #ifdef WITH_PYTHON_MODULE { /* Manually load all modules */ struct _inittab *inittab_item; PyObject *sys_modules = PyImport_GetModuleDict(); for (inittab_item = bpy_internal_modules; inittab_item->name; inittab_item++) { PyObject *mod = inittab_item->initfunc(); if (mod) { PyDict_SetItemString(sys_modules, inittab_item->name, mod); } else { PyErr_Print(); PyErr_Clear(); } // Py_DECREF(mod); /* ideally would decref, but in this case we never want to free */ } } #endif /* bpy.* and lets us import it */ BPy_init_modules(); bpy_import_init(PyEval_GetBuiltins()); pyrna_alloc_types(); #ifndef WITH_PYTHON_MODULE /* py module runs atexit when bpy is freed */ BPY_atexit_register(); /* this can init any time */ py_tstate = PyGILState_GetThisThreadState(); PyEval_ReleaseThread(py_tstate); #endif }
static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure)) { return PyC_UnicodeFromByte(BLI_temporary_dir()); }