14#define PY_SSIZE_T_CLEAN
29#include "RNA_prototypes.hh"
69 ".. function:: script_paths()\n"
71 " Return 2 paths to blender scripts directories.\n"
73 " :return: (system, user) strings will be empty when not found.\n"
74 " :rtype: tuple[str, str]\n");
77 PyObject *
ret = PyTuple_New(2);
83 PyTuple_SET_ITEM(
ret, 0, item);
87 PyTuple_SET_ITEM(
ret, 1, item);
97 PyObject *py_list =
static_cast<PyObject *
>(bpath_data->
user_data);
105 ".. function:: blend_paths(*, absolute=False, packed=False, local=False)\n"
107 " Returns a list of paths to external files referenced by the loaded .blend file.\n"
109 " :arg absolute: When true the paths returned are made absolute.\n"
110 " :type absolute: bool\n"
111 " :arg packed: When true skip file paths for packed data.\n"
112 " :type packed: bool\n"
113 " :arg local: When true skip linked library paths.\n"
114 " :type local: bool\n"
115 " :return: path list.\n"
116 " :rtype: list[str]\n");
126 static const char *_keywords[] = {
"absolute",
"packed",
"local",
nullptr};
127 static _PyArg_Parser _parser = {
137 if (!_PyArg_ParseTupleAndKeywordsFast(args,
160 list = PyList_New(0);
175 ".. function:: flip_name(name, *, strip_digits=False)\n"
177 " Flip a name between left/right sides, useful for \n"
178 " mirroring bone names.\n"
180 " :arg name: Bone name to flip.\n"
182 " :arg strip_digits: Whether to remove ``.###`` suffix.\n"
183 " :type strip_digits: bool\n"
184 " :return: The flipped name.\n"
188 const char *name_src =
nullptr;
189 Py_ssize_t name_src_len;
190 bool strip_digits =
false;
192 static const char *_keywords[] = {
"",
"strip_digits",
nullptr};
193 static _PyArg_Parser _parser = {
202 if (!_PyArg_ParseTupleAndKeywordsFast(
203 args, kw, &_parser, &name_src, &name_src_len,
PyC_ParseBool, &strip_digits))
210 const size_t size = name_src_len + 2;
211 char *name_dst =
static_cast<char *
>(PyMem_MALLOC(
size));
214 PyObject *
result = PyUnicode_FromStringAndSize(name_dst, name_dst_len);
216 PyMem_FREE(name_dst);
234 static const char *_keywords[] = {
"type",
"path",
nullptr};
235 static _PyArg_Parser _parser = {
244 if (!_PyArg_ParseTupleAndKeywordsFast(args,
266 bpy_system_resource_doc,
267 ".. function:: system_resource(type, *, path=\"\")\n"
269 " Return a system resource path.\n"
271 " :arg type: string in ['DATAFILES', 'SCRIPTS', 'EXTENSIONS', 'PYTHON'].\n"
273 " :arg path: Optional subdirectory.\n"
274 " :type path: str | bytes\n");
288 static const char *_keywords[] = {
"type",
"path",
nullptr};
289 static _PyArg_Parser _parser = {
298 if (!_PyArg_ParseTupleAndKeywordsFast(args,
317 bpy_resource_path_doc,
318 ".. function:: resource_path(type, *, major=bpy.app.version[0], minor=bpy.app.version[1])\n"
320 " Return the base path for storing system files.\n"
322 " :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
324 " :arg major: major version, defaults to current.\n"
325 " :type major: int\n"
326 " :arg minor: minor version, defaults to current.\n"
327 " :type minor: str\n"
328 " :return: the resource path (not necessarily existing).\n"
342 static const char *_keywords[] = {
"type",
"major",
"minor",
nullptr};
343 static _PyArg_Parser _parser = {
353 if (!_PyArg_ParseTupleAndKeywordsFast(
368 bpy_driver_secure_code_test_doc,
369 ".. function:: _driver_secure_code_test(code, *, namespace=None, verbose=False)\n"
371 " Test if the script should be considered trusted.\n"
373 " :arg code: The code to test.\n"
374 " :type code: code\n"
375 " :arg namespace: The namespace of values which are allowed.\n"
376 " :type namespace: dict[str, Any]\n"
377 " :arg verbose: Print the reason for considering insecure to the ``stderr``.\n"
378 " :type verbose: bool\n"
379 " :return: True when the script is considered trusted.\n"
384 PyObject *py_namespace =
nullptr;
386 static const char *_keywords[] = {
"code",
"namespace",
"verbose",
nullptr};
387 static _PyArg_Parser _parser = {
393 ":driver_secure_code_test",
397 if (!_PyArg_ParseTupleAndKeywordsFast(args,
414 bpy_escape_identifier_doc,
415 ".. function:: escape_identifier(string)\n"
417 " Simple string escaping function used for animation paths.\n"
419 " :arg string: text\n"
420 " :type string: str\n"
421 " :return: The escaped string.\n"
425 Py_ssize_t value_str_len;
426 const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
428 if (value_str ==
nullptr) {
429 PyErr_SetString(PyExc_TypeError,
"expected a string");
433 const size_t size = (value_str_len * 2) + 1;
434 char *value_escape_str =
static_cast<char *
>(PyMem_MALLOC(
size));
435 const Py_ssize_t value_escape_str_len =
BLI_str_escape(value_escape_str, value_str,
size);
437 PyObject *value_escape;
438 if (value_escape_str_len == value_str_len) {
440 value_escape = value;
443 value_escape = PyUnicode_FromStringAndSize(value_escape_str, value_escape_str_len);
446 PyMem_FREE(value_escape_str);
453 bpy_unescape_identifier_doc,
454 ".. function:: unescape_identifier(string)\n"
456 " Simple string un-escape function used for animation paths.\n"
457 " This performs the reverse of :func:`escape_identifier`.\n"
459 " :arg string: text\n"
460 " :type string: str\n"
461 " :return: The un-escaped string.\n"
465 Py_ssize_t value_str_len;
466 const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
468 if (value_str ==
nullptr) {
469 PyErr_SetString(PyExc_TypeError,
"expected a string");
473 const size_t size = value_str_len + 1;
474 char *value_unescape_str =
static_cast<char *
>(PyMem_MALLOC(
size));
475 const Py_ssize_t value_unescape_str_len =
BLI_str_unescape(value_unescape_str, value_str,
size);
477 PyObject *value_unescape;
478 if (value_unescape_str_len == value_str_len) {
480 value_unescape = value;
483 value_unescape = PyUnicode_FromStringAndSize(value_unescape_str, value_unescape_str_len);
486 PyMem_FREE(value_unescape_str);
488 return value_unescape;
506 bpy_context_members_doc,
507 ".. function:: context_members()\n"
509 " :return: A dict where the key is the context and the value is a tuple of it's members.\n"
510 " :rtype: dict[str, tuple[str]]\n");
517 } context_members_all[] = {
530 for (
int context_index = 0; context_index <
ARRAY_SIZE(context_members_all); context_index++) {
531 const char *
name = context_members_all[context_index].name;
532 const char **dir = context_members_all[context_index].dir;
534 for (
i = 0; dir[
i];
i++) {
538 for (
i = 0; dir[
i];
i++) {
539 PyTuple_SET_ITEM(
members,
i, PyUnicode_FromString(dir[
i]));
554 bpy_rna_enum_items_static_doc,
555 ".. function:: rna_enum_items_static()\n"
557 " :return: A dict where the key the name of the enum, the value is a tuple of enum items.\n"
558 " :rtype: dict[str, tuple[:class:`bpy.types.EnumPropertyItem`]]\n");
559static PyObject *bpy_rna_enum_items_static(PyObject * )
561#define DEF_ENUM(id) {STRINGIFY(id), id},
573 PyObject *value = PyTuple_New(items_count);
574 for (
int item_index = 0; item_index < items_count; item_index++) {
576 nullptr, &RNA_EnumPropertyItem, (
void *)&items[item_index]);
579 PyDict_SetItemString(
result, enum_info[
i].
id, value);
588 bpy_ghost_backend_doc,
589 ".. function:: _ghost_backend()\n"
591 " :return: An identifier for the GHOST back-end.\n"
607 bpy_wm_capabilities_doc,
608 ".. function:: _wm_capabilities()\n"
610 " :return: A dictionary of capabilities (string keys, boolean values).\n"
611 " :rtype: dict[str, bool]\n");
614 PyObject *py_id_capabilities = PyUnicode_FromString(
"_wm_capabilities_");
615 PyObject *
result =
nullptr;
626#define SetFlagItem(x) \
627 PyDict_SetItemString(result, STRINGIFY(x), PyBool_FromLong((WM_CAPABILITY_##x) & flag));
636 PyObject_SetAttr(
self, py_id_capabilities,
result);
651# pragma clang diagnostic push
652# pragma clang diagnostic ignored "-Wcast-function-type"
654# pragma GCC diagnostic push
655# pragma GCC diagnostic ignored "-Wcast-function-type"
660 {
"script_paths", (PyCFunction)
bpy_script_paths, METH_NOARGS, bpy_script_paths_doc},
663 METH_VARARGS | METH_KEYWORDS,
664 bpy_blend_paths_doc},
665 {
"flip_name", (PyCFunction)
bpy_flip_name, METH_VARARGS | METH_KEYWORDS, bpy_flip_name_doc},
666 {
"user_resource", (PyCFunction)
bpy_user_resource, METH_VARARGS | METH_KEYWORDS,
nullptr},
669 METH_VARARGS | METH_KEYWORDS,
670 bpy_system_resource_doc},
673 METH_VARARGS | METH_KEYWORDS,
674 bpy_resource_path_doc},
676 {
"unescape_identifier",
679 bpy_unescape_identifier_doc},
680 {
"context_members", (PyCFunction)
bpy_context_members, METH_NOARGS, bpy_context_members_doc},
681 {
"rna_enum_items_static",
682 (PyCFunction)bpy_rna_enum_items_static,
684 bpy_rna_enum_items_static_doc},
687 {
"_driver_secure_code_test",
689 METH_VARARGS | METH_KEYWORDS,
690 bpy_driver_secure_code_test_doc},
691 {
"_ghost_backend", (PyCFunction)
bpy_ghost_backend, METH_NOARGS, bpy_ghost_backend_doc},
692 {
"_wm_capabilities", (PyCFunction)
bpy_wm_capabilities, METH_NOARGS, bpy_wm_capabilities_doc},
694 {
nullptr,
nullptr, 0,
nullptr},
699# pragma clang diagnostic pop
701# pragma GCC diagnostic pop
707 PyObject *
mod = PyImport_ImportModuleLevel(modname,
nullptr,
nullptr,
nullptr, 0);
726 if (modpath.has_value()) {
728 PyObject *sys_path = PySys_GetObject(
"path");
730 PyList_Insert(sys_path, 0, py_modpath);
734 printf(
"bpy: couldn't find 'scripts/modules', blender probably won't start.\n");
743 mod = PyModule_New(
"_bpy");
746 PyDict_SetItemString(PyImport_GetModuleDict(),
"_bpy",
mod);
753 PyModule_AddObject(
mod,
"types", bpy_types);
766 PyObject *bpy_types_dict_dummy = PyDict_New();
770 BLI_assert(PyDict_GET_SIZE(bpy_types_dict_dummy) == 0);
773 PyObject *bpy_types_module_py_dict = PyModule_GetDict(bpy_types_module_py);
793#define PYMODULE_ADD_METHOD(mod, meth) \
794 PyModule_AddObject(mod, (meth)->ml_name, (PyObject *)PyCFunction_New(meth, mod))
799 BLI_assert((m->ml_flags & (METH_CLASS | METH_STATIC)) == 0);
814#undef PYMODULE_ADD_METHOD
std::optional< std::string > BKE_appdir_folder_id_user_notest(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
std::optional< std::string > BKE_appdir_resource_path_id_with_version(int folder_id, bool check_is_dir, int version)
@ BLENDER_RESOURCE_PATH_SYSTEM
@ BLENDER_RESOURCE_PATH_LOCAL
@ BLENDER_RESOURCE_PATH_USER
std::optional< std::string > BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
@ BLENDER_USER_EXTENSIONS
@ BLENDER_SYSTEM_DATAFILES
@ BLENDER_SYSTEM_EXTENSIONS
@ BKE_BPATH_FOREACH_PATH_SKIP_LINKED
@ BKE_BPATH_FOREACH_PATH_ABSOLUTE
@ BKE_BPATH_FOREACH_PATH_SKIP_PACKED
void BKE_bpath_foreach_path_main(BPathForeachPathData *bpath_data)
size_t size_t size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, size_t src_maxncpy) ATTR_NONNULL(1
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
size_t BLI_string_flip_side_name(char *name_dst, const char *name_src, bool strip_number, size_t name_dst_maxncpy) ATTR_NONNULL(1
PyObject * Freestyle_Init()
#define PYMODULE_ADD_METHOD(mod, meth)
static PyObject * bpy_ghost_backend(PyObject *)
static PyObject * bpy_unescape_identifier(PyObject *, PyObject *value)
static PyObject * bpy_resource_path(PyObject *, PyObject *args, PyObject *kw)
static PyObject * bpy_blend_paths(PyObject *, PyObject *args, PyObject *kw)
static PyObject * bpy_escape_identifier(PyObject *, PyObject *value)
static PyMethodDef bpy_methods[]
PyObject * bpy_package_py
void BPy_init_modules(bContext *C)
static PyObject * bpy_driver_secure_code_test(PyObject *, PyObject *args, PyObject *kw)
static PyObject * bpy_flip_name(PyObject *, PyObject *args, PyObject *kw)
static PyObject * bpy_import_test(const char *modname)
static bool bpy_blend_foreach_path_cb(BPathForeachPathData *bpath_data, char *, size_t, const char *path_src)
PyDoc_STRVAR(bpy_script_paths_doc, ".. function:: script_paths()\n" "\n" " Return 2 paths to blender scripts directories.\n" "\n" " :return: (system, user) strings will be empty when not found.\n" " :rtype: tuple[str, str]\n")
const char * sequencer_context_dir[]
static PyObject * bpy_wm_capabilities(PyObject *self)
static PyObject * bpy_context_members(PyObject *)
static PyObject * bpy_system_resource(PyObject *, PyObject *args, PyObject *kw)
static PyObject * bpy_script_paths(PyObject *)
static PyObject * bpy_user_resource(PyObject *, PyObject *args, PyObject *kw)
PyObject * BPY_app_struct()
PyMethodDef BPY_cli_command_register_def
PyMethodDef BPY_cli_command_unregister_def
bool BPY_driver_secure_bytecode_test(PyObject *expr_code, PyObject *py_namespace, const bool verbose)
PyObject * BPyInit_geometry_set_type()
PyObject * BPyInit_inline_shader_nodes_type()
int BPY_library_load_type_ready()
PyObject * BPY_msgbus_module()
PyObject * BPY_operator_module()
PyObject * BPY_rna_props()
PyMethodDef meth_bpy_owner_id_set
PyObject * BPY_rna_module()
PyMethodDef meth_bpy_owner_id_get
void BPY_rna_types_finalize_external_types(PyObject *submodule)
void BPY_rna_types_dict_set(PyObject *dict)
PyObject * BPY_rna_types()
PyMethodDef meth_bpy_unregister_class
PyMethodDef meth_bpy_register_class
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
BPy_StructRNA * bpy_context_module
int BPY_rna_data_context_type_ready()
bool BPY_rna_gizmo_module(PyObject *mod_par)
void BPY_rna_types_extend_capi()
PyObject * BPY_utils_previews_module()
PyObject * BPY_utils_units()
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
btMatrix3x3 absolute() const
Return the matrix with all values non negative.
const char * buttons_context_dir[]
const char * file_context_dir[]
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
void IDPropertyUIData_Init_Types()
const char * image_context_dir[]
const char * node_context_dir[]
int PyC_ParseUnicodeAsBytesAndSize(PyObject *o, void *p)
int PyC_ParseStringEnum(PyObject *o, void *p)
PyObject * PyC_UnicodeFromBytes(const char *str)
PyObject * PyC_UnicodeFromStdStr(const std::string &str)
int PyC_ParseBool(PyObject *o, void *p)
header-only compatibility defines.
#define PyObject_GetOptionalAttr
#define PY_ARG_PARSER_HEAD_COMPAT()
uint RNA_enum_items_count(const EnumPropertyItem *item)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
const char * screen_context_dir[]
const char * clip_context_dir[]
const char * text_context_dir[]
BPathForeachPathFunctionCallback callback_function
const char * view3d_context_dir[]
const char * WM_ghost_backend()
eWM_CapabilitiesFlag WM_capabilities_flag()