2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Campbell Barton
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file blender/python/intern/bpy.c
24 * \ingroup pythonintern
26 * This file defines the '_bpy' module which is used by python's 'bpy' package
27 * to access C defined builtin functions.
28 * A script writer should never directly access this module.
33 #include "BLI_utildefines.h"
34 #include "BLI_path_util.h"
35 #include "BLI_string.h"
38 #include "BKE_global.h" /* XXX, G.main only */
39 #include "BKE_blender.h"
40 #include "BKE_bpath.h"
42 #include "RNA_types.h"
43 #include "RNA_access.h"
49 #include "bpy_props.h"
50 #include "bpy_library.h"
51 #include "bpy_operator.h"
53 #include "MEM_guardedalloc.h"
55 /* external util modules */
56 #include "../generic/idprop_py_api.h"
57 #include "../generic/bgl.h"
58 #include "../generic/blf_py_api.h"
59 #include "../mathutils/mathutils.h"
62 # include "BPy_Freestyle.h"
65 PyObject *bpy_package_py = NULL;
67 PyDoc_STRVAR(bpy_script_paths_doc,
68 ".. function:: script_paths()\n"
70 " Return 2 paths to blender scripts directories.\n"
72 " :return: (system, user) strings will be empty when not found.\n"
73 " :rtype: tuple of strings\n"
75 static PyObject *bpy_script_paths(PyObject *UNUSED(self))
77 PyObject *ret = PyTuple_New(2);
81 path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL);
82 item = PyUnicode_DecodeFSDefault(path ? path : "");
83 BLI_assert(item != NULL);
84 PyTuple_SET_ITEM(ret, 0, item);
85 path = BLI_get_folder(BLENDER_USER_SCRIPTS, NULL);
86 item = PyUnicode_DecodeFSDefault(path ? path : "");
87 BLI_assert(item != NULL);
88 PyTuple_SET_ITEM(ret, 1, item);
93 static bool bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
95 PyObject *list = (PyObject *)userdata;
96 PyObject *item = PyUnicode_DecodeFSDefault(path_src);
97 PyList_Append(list, item);
99 return false; /* never edits the path */
102 PyDoc_STRVAR(bpy_blend_paths_doc,
103 ".. function:: blend_paths(absolute=False, packed=False, local=False)\n"
105 " Returns a list of paths to external files referenced by the loaded .blend file.\n"
107 " :arg absolute: When true the paths returned are made absolute.\n"
108 " :type absolute: boolean\n"
109 " :arg packed: When true skip file paths for packed data.\n"
110 " :type packed: boolean\n"
111 " :arg local: When true skip linked library paths.\n"
112 " :type local: boolean\n"
113 " :return: path list.\n"
114 " :rtype: list of strings\n"
116 static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
121 int absolute = false;
124 static const char *kwlist[] = {"absolute", "packed", "local", NULL};
126 if (!PyArg_ParseTupleAndKeywords(args, kw, "|iii:blend_paths",
127 (char **)kwlist, &absolute, &packed, &local))
132 if (absolute) flag |= BKE_BPATH_TRAVERSE_ABS;
133 if (!packed) flag |= BKE_BPATH_TRAVERSE_SKIP_PACKED;
134 if (local) flag |= BKE_BPATH_TRAVERSE_SKIP_LIBRARY;
136 list = PyList_New(0);
138 BKE_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list);
144 // PyDoc_STRVAR(bpy_user_resource_doc[] = // now in bpy/utils.py
145 static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
148 const char *subdir = NULL;
150 static const char *kwlist[] = {"type", "subdir", NULL};
154 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", (char **)kwlist, &type, &subdir))
157 /* stupid string compare */
158 if (STREQ(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES;
159 else if (STREQ(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG;
160 else if (STREQ(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS;
161 else if (STREQ(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE;
163 PyErr_SetString(PyExc_ValueError, "invalid resource argument");
167 /* same logic as BLI_get_folder_create(), but best leave it up to the script author to create */
168 path = BLI_get_folder(folder_id, subdir);
171 path = BLI_get_user_folder_notest(folder_id, subdir);
173 return PyUnicode_DecodeFSDefault(path ? path : "");
176 PyDoc_STRVAR(bpy_resource_path_doc,
177 ".. function:: resource_path(type, major=bpy.app.version[0], minor=bpy.app.version[1])\n"
179 " Return the base path for storing system files.\n"
181 " :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
182 " :type type: string\n"
183 " :arg major: major version, defaults to current.\n"
184 " :type major: int\n"
185 " :arg minor: minor version, defaults to current.\n"
186 " :type minor: string\n"
187 " :return: the resource path (not necessarily existing).\n"
190 static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
193 int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
194 static const char *kwlist[] = {"type", "major", "minor", NULL};
198 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ii:resource_path", (char **)kwlist, &type, &major, &minor))
201 /* stupid string compare */
202 if (STREQ(type, "USER")) folder_id = BLENDER_RESOURCE_PATH_USER;
203 else if (STREQ(type, "LOCAL")) folder_id = BLENDER_RESOURCE_PATH_LOCAL;
204 else if (STREQ(type, "SYSTEM")) folder_id = BLENDER_RESOURCE_PATH_SYSTEM;
206 PyErr_SetString(PyExc_ValueError, "invalid resource argument");
210 path = BLI_get_folder_version(folder_id, (major * 100) + minor, false);
212 return PyUnicode_DecodeFSDefault(path ? path : "");
215 PyDoc_STRVAR(bpy_escape_identifier_doc,
216 ".. function:: escape_identifier(string)\n"
218 " Simple string escaping function used for animation paths.\n"
220 " :arg string: text\n"
221 " :type string: string\n"
222 " :return: The escaped string.\n"
225 static PyObject *bpy_escape_identifier(PyObject *UNUSED(self), PyObject *value)
227 const char *value_str;
228 Py_ssize_t value_str_len;
230 char *value_escape_str;
231 Py_ssize_t value_escape_str_len;
232 PyObject *value_escape;
235 value_str = _PyUnicode_AsStringAndSize(value, &value_str_len);
237 if (value_str == NULL) {
238 PyErr_SetString(PyExc_TypeError, "expected a string");
242 size = (value_str_len * 2) + 1;
243 value_escape_str = PyMem_MALLOC(size);
244 value_escape_str_len = BLI_strescape(value_escape_str, value_str, size);
246 if (value_escape_str_len == value_str_len) {
248 value_escape = value;
251 value_escape = PyUnicode_FromStringAndSize(value_escape_str, value_escape_str_len);
254 PyMem_FREE(value_escape_str);
259 static PyMethodDef meth_bpy_script_paths =
260 {"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
261 static PyMethodDef meth_bpy_blend_paths =
262 {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS | METH_KEYWORDS, bpy_blend_paths_doc};
263 static PyMethodDef meth_bpy_user_resource =
264 {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS | METH_KEYWORDS, NULL};
265 static PyMethodDef meth_bpy_resource_path =
266 {"resource_path", (PyCFunction)bpy_resource_path, METH_VARARGS | METH_KEYWORDS, bpy_resource_path_doc};
267 static PyMethodDef meth_bpy_escape_identifier =
268 {"escape_identifier", (PyCFunction)bpy_escape_identifier, METH_O, bpy_escape_identifier_doc};
270 static PyObject *bpy_import_test(const char *modname)
272 PyObject *mod = PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
285 /******************************************************************************
286 * Description: Creates the bpy module and adds it to sys.modules for importing
287 ******************************************************************************/
288 void BPy_init_modules(void)
290 extern BPy_StructRNA *bpy_context_module;
294 /* Needs to be first since this dir is needed for future modules */
295 const char * const modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules");
297 // printf("bpy: found module path '%s'.\n", modpath);
298 PyObject *sys_path = PySys_GetObject("path"); /* borrow */
299 PyObject *py_modpath = PyUnicode_FromString(modpath);
300 PyList_Insert(sys_path, 0, py_modpath); /* add first */
301 Py_DECREF(py_modpath);
304 printf("bpy: couldnt find 'scripts/modules', blender probably wont start.\n");
306 /* stand alone utility modules not related to blender directly */
307 IDProp_Init_Types(); /* not actually a submodule, just types */
308 #ifdef WITH_FREESTYLE
312 mod = PyModule_New("_bpy");
314 /* add the module so we can import it */
315 PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod);
318 /* run first, initializes rna types */
321 /* needs to be first so bpy_types can run */
322 PyModule_AddObject(mod, "types", BPY_rna_types());
324 /* metaclass for idprop types, bpy_types.py needs access */
325 PyModule_AddObject(mod, "StructMetaPropGroup", (PyObject *)&pyrna_struct_meta_idprop_Type);
327 /* needs to be first so bpy_types can run */
328 BPY_library_module(mod);
330 bpy_import_test("bpy_types");
331 PyModule_AddObject(mod, "data", BPY_rna_module()); /* imports bpy_types by running this */
332 bpy_import_test("bpy_types");
333 PyModule_AddObject(mod, "props", BPY_rna_props());
334 /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
335 PyModule_AddObject(mod, "ops", BPY_operator_module());
336 PyModule_AddObject(mod, "app", BPY_app_struct());
339 RNA_pointer_create(NULL, &RNA_Context, (void *)BPy_GetContext(), &ctx_ptr);
340 bpy_context_module = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ctx_ptr);
341 /* odd that this is needed, 1 ref on creation and another for the module
342 * but without we get a crash on exit */
343 Py_INCREF(bpy_context_module);
345 PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
347 /* register bpy/rna classmethod callbacks */
348 BPY_rna_register_cb();
350 /* utility func's that have nowhere else to go */
351 PyModule_AddObject(mod, meth_bpy_script_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL));
352 PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
353 PyModule_AddObject(mod, meth_bpy_user_resource.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_user_resource, NULL));
354 PyModule_AddObject(mod, meth_bpy_resource_path.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL));
355 PyModule_AddObject(mod, meth_bpy_escape_identifier.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_escape_identifier, NULL));
357 /* register funcs (bpy_rna.c) */
358 PyModule_AddObject(mod, meth_bpy_register_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_register_class, NULL));
359 PyModule_AddObject(mod, meth_bpy_unregister_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_unregister_class, NULL));
361 /* add our own modules dir, this is a python package */
362 bpy_package_py = bpy_import_test("bpy");