14#define PY_SSIZE_T_CLEAN
29#include "RNA_prototypes.hh"
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[str, str]\n");
76 PyObject *
ret = PyTuple_New(2);
82 PyTuple_SET_ITEM(
ret, 0, item);
86 PyTuple_SET_ITEM(
ret, 1, item);
96 PyObject *py_list =
static_cast<PyObject *
>(bpath_data->
user_data);
104 ".. function:: blend_paths(absolute=False, packed=False, local=False)\n"
106 " Returns a list of paths to external files referenced by the loaded .blend file.\n"
108 " :arg absolute: When true the paths returned are made absolute.\n"
109 " :type absolute: bool\n"
110 " :arg packed: When true skip file paths for packed data.\n"
111 " :type packed: bool\n"
112 " :arg local: When true skip linked library paths.\n"
113 " :type local: bool\n"
114 " :return: path list.\n"
115 " :rtype: list[str]\n");
125 static const char *_keywords[] = {
"absolute",
"packed",
"local",
nullptr};
126 static _PyArg_Parser _parser = {
136 if (!_PyArg_ParseTupleAndKeywordsFast(args,
159 list = PyList_New(0);
174 ".. function:: flip_name(name, strip_digits=False)\n"
176 " Flip a name between left/right sides, useful for \n"
177 " mirroring bone names.\n"
179 " :arg name: Bone name to flip.\n"
181 " :arg strip_digits: Whether to remove ``.###`` suffix.\n"
182 " :type strip_digits: bool\n"
183 " :return: The flipped name.\n"
187 const char *name_src =
nullptr;
188 Py_ssize_t name_src_len;
189 bool strip_digits =
false;
191 static const char *_keywords[] = {
"",
"strip_digits",
nullptr};
192 static _PyArg_Parser _parser = {
201 if (!_PyArg_ParseTupleAndKeywordsFast(
202 args, kw, &_parser, &name_src, &name_src_len,
PyC_ParseBool, &strip_digits))
209 const size_t size = name_src_len + 2;
210 char *name_dst =
static_cast<char *
>(PyMem_MALLOC(
size));
213 PyObject *
result = PyUnicode_FromStringAndSize(name_dst, name_dst_len);
215 PyMem_FREE(name_dst);
233 static const char *_keywords[] = {
"type",
"path",
nullptr};
234 static _PyArg_Parser _parser = {
243 if (!_PyArg_ParseTupleAndKeywordsFast(args,
265 bpy_system_resource_doc,
266 ".. function:: system_resource(type, path=\"\")\n"
268 " Return a system resource path.\n"
270 " :arg type: string in ['DATAFILES', 'SCRIPTS', 'EXTENSIONS', 'PYTHON'].\n"
272 " :arg path: Optional subdirectory.\n"
273 " :type path: str | bytes\n");
287 static const char *_keywords[] = {
"type",
"path",
nullptr};
288 static _PyArg_Parser _parser = {
297 if (!_PyArg_ParseTupleAndKeywordsFast(args,
316 bpy_resource_path_doc,
317 ".. function:: resource_path(type, major=bpy.app.version[0], minor=bpy.app.version[1])\n"
319 " Return the base path for storing system files.\n"
321 " :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
323 " :arg major: major version, defaults to current.\n"
324 " :type major: int\n"
325 " :arg minor: minor version, defaults to current.\n"
326 " :type minor: str\n"
327 " :return: the resource path (not necessarily existing).\n"
341 static const char *_keywords[] = {
"type",
"major",
"minor",
nullptr};
342 static _PyArg_Parser _parser = {
352 if (!_PyArg_ParseTupleAndKeywordsFast(
367 bpy_driver_secure_code_test_doc,
368 ".. function:: _driver_secure_code_test(code)\n"
370 " Test if the script should be considered trusted.\n"
372 " :arg code: The code to test.\n"
373 " :type code: code\n"
374 " :arg namespace: The namespace of values which are allowed.\n"
375 " :type namespace: dict[str, Any]\n"
376 " :arg verbose: Print the reason for considering insecure to the ``stderr``.\n"
377 " :type verbose: bool\n"
378 " :return: True when the script is considered trusted.\n"
383 PyObject *py_namespace =
nullptr;
385 static const char *_keywords[] = {
"code",
"namespace",
"verbose",
nullptr};
386 static _PyArg_Parser _parser = {
392 ":driver_secure_code_test",
396 if (!_PyArg_ParseTupleAndKeywordsFast(args,
413 bpy_escape_identifier_doc,
414 ".. function:: escape_identifier(string)\n"
416 " Simple string escaping function used for animation paths.\n"
418 " :arg string: text\n"
419 " :type string: str\n"
420 " :return: The escaped string.\n"
424 Py_ssize_t value_str_len;
425 const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
427 if (value_str ==
nullptr) {
428 PyErr_SetString(PyExc_TypeError,
"expected a string");
432 const size_t size = (value_str_len * 2) + 1;
433 char *value_escape_str =
static_cast<char *
>(PyMem_MALLOC(
size));
434 const Py_ssize_t value_escape_str_len =
BLI_str_escape(value_escape_str, value_str,
size);
436 PyObject *value_escape;
437 if (value_escape_str_len == value_str_len) {
439 value_escape = value;
442 value_escape = PyUnicode_FromStringAndSize(value_escape_str, value_escape_str_len);
445 PyMem_FREE(value_escape_str);
452 bpy_unescape_identifier_doc,
453 ".. function:: unescape_identifier(string)\n"
455 " Simple string un-escape function used for animation paths.\n"
456 " This performs the reverse of :func:`escape_identifier`.\n"
458 " :arg string: text\n"
459 " :type string: str\n"
460 " :return: The un-escaped string.\n"
464 Py_ssize_t value_str_len;
465 const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
467 if (value_str ==
nullptr) {
468 PyErr_SetString(PyExc_TypeError,
"expected a string");
472 const size_t size = value_str_len + 1;
473 char *value_unescape_str =
static_cast<char *
>(PyMem_MALLOC(
size));
474 const Py_ssize_t value_unescape_str_len =
BLI_str_unescape(value_unescape_str, value_str,
size);
476 PyObject *value_unescape;
477 if (value_unescape_str_len == value_str_len) {
479 value_unescape = value;
482 value_unescape = PyUnicode_FromStringAndSize(value_unescape_str, value_unescape_str_len);
485 PyMem_FREE(value_unescape_str);
487 return value_unescape;
505 bpy_context_members_doc,
506 ".. function:: context_members()\n"
508 " :return: A dict where the key is the context and the value is a tuple of it's members.\n"
509 " :rtype: dict[str, tuple[str]]\n");
516 } context_members_all[] = {
529 for (
int context_index = 0; context_index <
ARRAY_SIZE(context_members_all); context_index++) {
530 const char *name = context_members_all[context_index].name;
531 const char **dir = context_members_all[context_index].dir;
533 for (
i = 0; dir[
i];
i++) {
537 for (
i = 0; dir[
i];
i++) {
538 PyTuple_SET_ITEM(
members,
i, PyUnicode_FromString(dir[
i]));
553 bpy_rna_enum_items_static_doc,
554 ".. function:: rna_enum_items_static()\n"
556 " :return: A dict where the key the name of the enum, the value is a tuple of enum items.\n"
557 " :rtype: dict[str, tuple[:class:`bpy.types.EnumPropertyItem`]]\n");
558static PyObject *bpy_rna_enum_items_static(PyObject * )
560#define DEF_ENUM(id) {STRINGIFY(id), id},
572 PyObject *value = PyTuple_New(items_count);
573 for (
int item_index = 0; item_index < items_count; item_index++) {
575 nullptr, &RNA_EnumPropertyItem, (
void *)&items[item_index]);
578 PyDict_SetItemString(
result, enum_info[
i].
id, value);
587 bpy_ghost_backend_doc,
588 ".. function:: _ghost_backend()\n"
590 " :return: An identifier for the GHOST back-end.\n"
606 bpy_wm_capabilities_doc,
607 ".. function:: _wm_capabilities()\n"
609 " :return: A dictionary of capabilities (string keys, boolean values).\n"
610 " :rtype: dict[str, bool]\n");
613 PyObject *py_id_capabilities = PyUnicode_FromString(
"_wm_capabilities_");
614 PyObject *
result =
nullptr;
625#define SetFlagItem(x) \
626 PyDict_SetItemString(result, STRINGIFY(x), PyBool_FromLong((WM_CAPABILITY_##x) & flag));
639 PyObject_SetAttr(
self, py_id_capabilities,
result);
648 Py_DECREF(py_id_capabilities);
654# pragma clang diagnostic push
655# pragma clang diagnostic ignored "-Wcast-function-type"
657# pragma GCC diagnostic push
658# pragma GCC diagnostic ignored "-Wcast-function-type"
663 {
"script_paths", (PyCFunction)
bpy_script_paths, METH_NOARGS, bpy_script_paths_doc},
666 METH_VARARGS | METH_KEYWORDS,
667 bpy_blend_paths_doc},
668 {
"flip_name", (PyCFunction)
bpy_flip_name, METH_VARARGS | METH_KEYWORDS, bpy_flip_name_doc},
669 {
"user_resource", (PyCFunction)
bpy_user_resource, METH_VARARGS | METH_KEYWORDS,
nullptr},
672 METH_VARARGS | METH_KEYWORDS,
673 bpy_system_resource_doc},
676 METH_VARARGS | METH_KEYWORDS,
677 bpy_resource_path_doc},
679 {
"unescape_identifier",
682 bpy_unescape_identifier_doc},
683 {
"context_members", (PyCFunction)
bpy_context_members, METH_NOARGS, bpy_context_members_doc},
684 {
"rna_enum_items_static",
685 (PyCFunction)bpy_rna_enum_items_static,
687 bpy_rna_enum_items_static_doc},
690 {
"_driver_secure_code_test",
692 METH_VARARGS | METH_KEYWORDS,
693 bpy_driver_secure_code_test_doc},
694 {
"_ghost_backend", (PyCFunction)
bpy_ghost_backend, METH_NOARGS, bpy_ghost_backend_doc},
695 {
"_wm_capabilities", (PyCFunction)
bpy_wm_capabilities, METH_NOARGS, bpy_wm_capabilities_doc},
697 {
nullptr,
nullptr, 0,
nullptr},
702# pragma clang diagnostic pop
704# pragma GCC diagnostic pop
710 PyObject *
mod = PyImport_ImportModuleLevel(modname,
nullptr,
nullptr,
nullptr, 0);
732 if (modpath.has_value()) {
734 PyObject *sys_path = PySys_GetObject(
"path");
736 PyList_Insert(sys_path, 0, py_modpath);
737 Py_DECREF(py_modpath);
740 printf(
"bpy: couldn't find 'scripts/modules', blender probably won't start.\n");
749 mod = PyModule_New(
"_bpy");
752 PyDict_SetItemString(PyImport_GetModuleDict(),
"_bpy",
mod);
758 PyModule_AddObject(
mod,
"types", bpy_types);
786#define PYMODULE_ADD_METHOD(mod, meth) \
787 PyModule_AddObject(mod, (meth)->ml_name, (PyObject *)PyCFunction_New(meth, mod))
792 BLI_assert((m->ml_flags & (METH_CLASS | METH_STATIC)) == 0);
807#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_USER_EXTENSIONS
@ BLENDER_SYSTEM_DATAFILES
@ BLENDER_SYSTEM_EXTENSIONS
std::optional< std::string > BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
@ BLENDER_RESOURCE_PATH_SYSTEM
@ BLENDER_RESOURCE_PATH_LOCAL
@ BLENDER_RESOURCE_PATH_USER
@ 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()
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)
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()