14#define PY_SSIZE_T_CLEAN
29#include "RNA_prototypes.hh"
67 ".. function:: script_paths()\n"
69 " Return 2 paths to blender scripts directories.\n"
71 " :return: (system, user) strings will be empty when not found.\n"
72 " :rtype: tuple[str, str]\n");
75 PyObject *
ret = PyTuple_New(2);
81 PyTuple_SET_ITEM(
ret, 0, item);
85 PyTuple_SET_ITEM(
ret, 1, item);
95 PyObject *py_list =
static_cast<PyObject *
>(bpath_data->
user_data);
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: bool\n"
109 " :arg packed: When true skip file paths for packed data.\n"
110 " :type packed: bool\n"
111 " :arg local: When true skip linked library paths.\n"
112 " :type local: bool\n"
113 " :return: path list.\n"
114 " :rtype: list[str]\n");
124 static const char *_keywords[] = {
"absolute",
"packed",
"local",
nullptr};
125 static _PyArg_Parser _parser = {
135 if (!_PyArg_ParseTupleAndKeywordsFast(args,
158 list = PyList_New(0);
163 path_data.flag =
flag;
164 path_data.user_data = list;
173 ".. function:: flip_name(name, strip_digits=False)\n"
175 " Flip a name between left/right sides, useful for \n"
176 " mirroring bone names.\n"
178 " :arg name: Bone name to flip.\n"
180 " :arg strip_digits: Whether to remove ``.###`` suffix.\n"
181 " :type strip_digits: bool\n"
182 " :return: The flipped name.\n"
186 const char *name_src =
nullptr;
187 Py_ssize_t name_src_len;
188 bool strip_digits =
false;
190 static const char *_keywords[] = {
"",
"strip_digits",
nullptr};
191 static _PyArg_Parser _parser = {
200 if (!_PyArg_ParseTupleAndKeywordsFast(
201 args, kw, &_parser, &name_src, &name_src_len,
PyC_ParseBool, &strip_digits))
208 const size_t size = name_src_len + 2;
209 char *name_dst =
static_cast<char *
>(PyMem_MALLOC(size));
212 PyObject *result = PyUnicode_FromStringAndSize(name_dst, name_dst_len);
214 PyMem_FREE(name_dst);
232 static const char *_keywords[] = {
"type",
"path",
nullptr};
233 static _PyArg_Parser _parser = {
242 if (!_PyArg_ParseTupleAndKeywordsFast(args,
264 bpy_system_resource_doc,
265 ".. function:: system_resource(type, path=\"\")\n"
267 " Return a system resource path.\n"
269 " :arg type: string in ['DATAFILES', 'SCRIPTS', 'EXTENSIONS', 'PYTHON'].\n"
271 " :arg path: Optional subdirectory.\n"
272 " :type path: str | bytes\n");
286 static const char *_keywords[] = {
"type",
"path",
nullptr};
287 static _PyArg_Parser _parser = {
296 if (!_PyArg_ParseTupleAndKeywordsFast(args,
315 bpy_resource_path_doc,
316 ".. function:: resource_path(type, major=bpy.app.version[0], minor=bpy.app.version[1])\n"
318 " Return the base path for storing system files.\n"
320 " :arg type: string in ['USER', 'LOCAL', 'SYSTEM'].\n"
322 " :arg major: major version, defaults to current.\n"
323 " :type major: int\n"
324 " :arg minor: minor version, defaults to current.\n"
325 " :type minor: str\n"
326 " :return: the resource path (not necessarily existing).\n"
340 static const char *_keywords[] = {
"type",
"major",
"minor",
nullptr};
341 static _PyArg_Parser _parser = {
351 if (!_PyArg_ParseTupleAndKeywordsFast(
358 type.value_found,
false, (major * 100) + minor);
366 bpy_driver_secure_code_test_doc,
367 ".. function:: _driver_secure_code_test(code)\n"
369 " Test if the script should be considered trusted.\n"
371 " :arg code: The code to test.\n"
372 " :type code: code\n"
373 " :arg namespace: The namespace of values which are allowed.\n"
374 " :type namespace: dict[str, Any]\n"
375 " :arg verbose: Print the reason for considering insecure to the ``stderr``.\n"
376 " :type verbose: bool\n"
377 " :return: True when the script is considered trusted.\n"
382 PyObject *py_namespace =
nullptr;
384 static const char *_keywords[] = {
"code",
"namespace",
"verbose",
nullptr};
385 static _PyArg_Parser _parser = {
391 ":driver_secure_code_test",
395 if (!_PyArg_ParseTupleAndKeywordsFast(args,
412 bpy_escape_identifier_doc,
413 ".. function:: escape_identifier(string)\n"
415 " Simple string escaping function used for animation paths.\n"
417 " :arg string: text\n"
418 " :type string: str\n"
419 " :return: The escaped string.\n"
423 Py_ssize_t value_str_len;
424 const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
426 if (value_str ==
nullptr) {
427 PyErr_SetString(PyExc_TypeError,
"expected a string");
431 const size_t size = (value_str_len * 2) + 1;
432 char *value_escape_str =
static_cast<char *
>(PyMem_MALLOC(size));
433 const Py_ssize_t value_escape_str_len =
BLI_str_escape(value_escape_str, value_str, size);
435 PyObject *value_escape;
436 if (value_escape_str_len == value_str_len) {
438 value_escape = value;
441 value_escape = PyUnicode_FromStringAndSize(value_escape_str, value_escape_str_len);
444 PyMem_FREE(value_escape_str);
451 bpy_unescape_identifier_doc,
452 ".. function:: unescape_identifier(string)\n"
454 " Simple string un-escape function used for animation paths.\n"
455 " This performs the reverse of :func:`escape_identifier`.\n"
457 " :arg string: text\n"
458 " :type string: str\n"
459 " :return: The un-escaped string.\n"
463 Py_ssize_t value_str_len;
464 const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
466 if (value_str ==
nullptr) {
467 PyErr_SetString(PyExc_TypeError,
"expected a string");
471 const size_t size = value_str_len + 1;
472 char *value_unescape_str =
static_cast<char *
>(PyMem_MALLOC(size));
473 const Py_ssize_t value_unescape_str_len =
BLI_str_unescape(value_unescape_str, value_str, size);
475 PyObject *value_unescape;
476 if (value_unescape_str_len == value_str_len) {
478 value_unescape = value;
481 value_unescape = PyUnicode_FromStringAndSize(value_unescape_str, value_unescape_str_len);
484 PyMem_FREE(value_unescape_str);
486 return value_unescape;
504 bpy_context_members_doc,
505 ".. function:: context_members()\n"
507 " :return: A dict where the key is the context and the value is a tuple of it's members.\n"
508 " :rtype: dict[str, tuple[str]]\n");
515 } context_members_all[] = {
527 PyObject *result = _PyDict_NewPresized(
ARRAY_SIZE(context_members_all));
528 for (
int context_index = 0; context_index <
ARRAY_SIZE(context_members_all); context_index++) {
529 const char *name = context_members_all[context_index].name;
530 const char **dir = context_members_all[context_index].dir;
532 for (i = 0; dir[i]; i++) {
535 PyObject *
members = PyTuple_New(i);
536 for (i = 0; dir[i]; i++) {
537 PyTuple_SET_ITEM(
members, i, PyUnicode_FromString(dir[i]));
539 PyDict_SetItemString(result, name,
members);
552 bpy_rna_enum_items_static_doc,
553 ".. function:: rna_enum_items_static()\n"
555 " :return: A dict where the key the name of the enum, the value is a tuple of enum items.\n"
556 " :rtype: dict[str, tuple[:class:`bpy.types.EnumPropertyItem`]]\n");
559#define DEF_ENUM(id) {STRINGIFY(id), id},
566 PyObject *result = _PyDict_NewPresized(
ARRAY_SIZE(enum_info));
567 for (
int i = 0; i <
ARRAY_SIZE(enum_info); i++) {
571 PyObject *value = PyTuple_New(items_count);
572 for (
int item_index = 0; item_index < items_count; item_index++) {
574 nullptr, &RNA_EnumPropertyItem, (
void *)&items[item_index]);
577 PyDict_SetItemString(result, enum_info[i].
id, value);
586 bpy_ghost_backend_doc,
587 ".. function:: _ghost_backend()\n"
589 " :return: An identifier for the GHOST back-end.\n"
605 bpy_wm_capabilities_doc,
606 ".. function:: _wm_capabilities()\n"
608 " :return: A dictionary of capabilities (string keys, boolean values).\n"
609 " :rtype: dict[str, bool]\n");
612 static _Py_Identifier PyId_capabilities = {
"_wm_capabilities_", -1};
614 PyObject *result =
nullptr;
615 switch (_PyObject_LookupAttrId(
self, &PyId_capabilities, &result)) {
625 result = PyDict_New();
629#define SetFlagItem(x) \
630 PyDict_SetItemString(result, STRINGIFY(x), PyBool_FromLong((WM_CAPABILITY_##x) & flag));
643 _PyObject_SetAttrId(
self, &PyId_capabilities, result);
647#if (defined(__GNUC__) && !defined(__clang__))
648# pragma GCC diagnostic push
649# pragma GCC diagnostic ignored "-Wcast-function-type"
653 {
"script_paths", (PyCFunction)
bpy_script_paths, METH_NOARGS, bpy_script_paths_doc},
656 METH_VARARGS | METH_KEYWORDS,
657 bpy_blend_paths_doc},
658 {
"flip_name", (PyCFunction)
bpy_flip_name, METH_VARARGS | METH_KEYWORDS, bpy_flip_name_doc},
659 {
"user_resource", (PyCFunction)
bpy_user_resource, METH_VARARGS | METH_KEYWORDS,
nullptr},
662 METH_VARARGS | METH_KEYWORDS,
663 bpy_system_resource_doc},
666 METH_VARARGS | METH_KEYWORDS,
667 bpy_resource_path_doc},
669 {
"unescape_identifier",
672 bpy_unescape_identifier_doc},
673 {
"context_members", (PyCFunction)
bpy_context_members, METH_NOARGS, bpy_context_members_doc},
674 {
"rna_enum_items_static",
677 bpy_rna_enum_items_static_doc},
680 {
"_driver_secure_code_test",
682 METH_VARARGS | METH_KEYWORDS,
683 bpy_driver_secure_code_test_doc},
684 {
"_ghost_backend", (PyCFunction)
bpy_ghost_backend, METH_NOARGS, bpy_ghost_backend_doc},
685 {
"_wm_capabilities", (PyCFunction)
bpy_wm_capabilities, METH_NOARGS, bpy_wm_capabilities_doc},
687 {
nullptr,
nullptr, 0,
nullptr},
690#if (defined(__GNUC__) && !defined(__clang__))
691# pragma GCC diagnostic pop
696 PyObject *
mod = PyImport_ImportModuleLevel(modname,
nullptr,
nullptr,
nullptr, 0);
718 if (modpath.has_value()) {
720 PyObject *sys_path = PySys_GetObject(
"path");
722 PyList_Insert(sys_path, 0, py_modpath);
723 Py_DECREF(py_modpath);
726 printf(
"bpy: couldn't find 'scripts/modules', blender probably won't start.\n");
735 mod = PyModule_New(
"_bpy");
738 PyDict_SetItemString(PyImport_GetModuleDict(),
"_bpy",
mod);
743 PyModule_AddObject(
mod,
"types", bpy_types);
776#define PYMODULE_ADD_METHOD(mod, meth) \
777 PyModule_AddObject(mod, (meth)->ml_name, (PyObject *)PyCFunction_New(meth, mod))
782 BLI_assert((m->ml_flags & (METH_CLASS | METH_STATIC)) == 0);
797#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()
const char * text_context_dir[]
#define PYMODULE_ADD_METHOD(mod, meth)
const char * buttons_context_dir[]
static PyObject * bpy_ghost_backend(PyObject *)
const char * file_context_dir[]
const char * screen_context_dir[]
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
const char * clip_context_dir[]
void BPy_init_modules(bContext *C)
static PyObject * bpy_driver_secure_code_test(PyObject *, PyObject *args, PyObject *kw)
const char * image_context_dir[]
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 * view3d_context_dir[]
const char * sequencer_context_dir[]
static PyObject * bpy_wm_capabilities(PyObject *self)
static PyObject * bpy_context_members(PyObject *)
const char * node_context_dir[]
static PyObject * bpy_rna_enum_items_static(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)
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()
btMatrix3x3 absolute() const
Return the matrix with all values non negative.
void IDPropertyUIData_Init_Types()
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 PY_ARG_PARSER_HEAD_COMPAT()
uint RNA_enum_items_count(const EnumPropertyItem *item)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
ccl_device_inline int mod(int x, int m)
const char * WM_ghost_backend()
eWM_CapabilitiesFlag WM_capabilities_flag()