diff options
Diffstat (limited to 'source/blender/python/intern')
19 files changed, 218 insertions, 44 deletions
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 7fe0b9455e6..3b3ffb321c3 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -655,7 +655,7 @@ void BPy_init_modules(struct bContext *C) PyModule_AddObject(mod, m->ml_name, (PyObject *)PyCFunction_New(m, NULL)); } - /* register funcs (bpy_rna.c) */ + /* Register functions (`bpy_rna.c`). */ PyModule_AddObject(mod, meth_bpy_register_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_register_class, NULL)); diff --git a/source/blender/python/intern/bpy.h b/source/blender/python/intern/bpy.h index 313385b7f5d..f62542bb342 100644 --- a/source/blender/python/intern/bpy.h +++ b/source/blender/python/intern/bpy.h @@ -12,7 +12,7 @@ extern "C" { struct bContext; -/** Creates the bpy module and adds it to `sys.modules` for importing. */ +/** Creates the `bpy` module and adds it to `sys.modules` for importing. */ void BPy_init_modules(struct bContext *C); extern PyObject *bpy_package_py; diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 939473ceaa0..70cf231bc26 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -79,8 +79,6 @@ static PyStructSequence_Field app_info_fields[] = { {"version_string", "The Blender version formatted as a string"}, {"version_cycle", "The release status of this build alpha/beta/rc/release"}, {"version_char", "Deprecated, always an empty string"}, - {"binary_path", - "The location of Blender's executable, useful for utilities that open new instances"}, {"background", "Boolean, True when blender is running without a user interface (started with -b)"}, {"factory_startup", "Boolean, True when blender is running with --factory-startup)"}, @@ -151,7 +149,6 @@ static PyObject *make_app_info(void) SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE)); SetStrItem(""); - SetStrItem(BKE_appdir_program_path()); SetObjItem(PyBool_FromLong(G.background)); SetObjItem(PyBool_FromLong(G.factory_startup)); @@ -345,6 +342,33 @@ static PyObject *bpy_app_autoexec_fail_message_get(PyObject *UNUSED(self), void return PyC_UnicodeFromByte(G.autoexec_fail); } +PyDoc_STRVAR(bpy_app_binary_path_doc, + "The location of Blender's executable, useful for utilities that open new instances. " + "Read-only unless Blender is built as a Python module - in this case the value is " + "an empty string which script authors may point to a Blender binary."); +static PyObject *bpy_app_binary_path_get(PyObject *UNUSED(self), void *UNUSED(closure)) +{ + return PyC_UnicodeFromByte(BKE_appdir_program_path()); +} + +static int bpy_app_binary_path_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure)) +{ +#ifndef WITH_PYTHON_MODULE + PyErr_SetString(PyExc_AttributeError, + "bpy.app.binary_path is only writable when built as a Python module"); + return -1; +#endif + PyObject *value_coerce = NULL; + const char *filepath = PyC_UnicodeAsByte(value, &value_coerce); + if (filepath == NULL) { + PyErr_Format(PyExc_ValueError, "expected a string or bytes, got %s", Py_TYPE(value)->tp_name); + return -1; + } + BKE_appdir_program_path_init(filepath); + Py_XDECREF(value_coerce); + return 0; +} + static PyGetSetDef bpy_app_getsets[] = { {"debug", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG}, {"debug_ffmpeg", @@ -450,7 +474,14 @@ static PyGetSetDef bpy_app_getsets[] = { (void *)G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET}, {"autoexec_fail_message", bpy_app_autoexec_fail_message_get, NULL, NULL, NULL}, - /* End-of-list marker. */ + /* Support script authors setting the Blender binary path to use, otherwise this value + * is not known when built as a Python module. */ + {"binary_path", + bpy_app_binary_path_get, + bpy_app_binary_path_set, + bpy_app_binary_path_doc, + NULL}, + {NULL, NULL, NULL, NULL, NULL}, }; @@ -528,7 +559,7 @@ PyObject *BPY_app_struct(void) BlenderAppType.tp_hash = (hashfunc) _Py_HashPointer; /* without this we can't do set(sys.modules) T29635. */ - /* kindof a hack ontop of PyStructSequence */ + /* Kind of a hack on top of #PyStructSequence. */ py_struct_seq_getset_init(); py_struct_seq_method_init(); diff --git a/source/blender/python/intern/bpy_app_icons.c b/source/blender/python/intern/bpy_app_icons.c index 3f884338bbb..918d96d9f44 100644 --- a/source/blender/python/intern/bpy_app_icons.c +++ b/source/blender/python/intern/bpy_app_icons.c @@ -166,7 +166,7 @@ static struct PyModuleDef M_AppIcons_module_def = { NULL, /* m_doc */ 0, /* m_size */ M_AppIcons_methods, /* m_methods */ - NULL, /* m_reload */ + NULL, /* m_slots */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ diff --git a/source/blender/python/intern/bpy_app_timers.c b/source/blender/python/intern/bpy_app_timers.c index 5a42ecfdbc8..4adc200357b 100644 --- a/source/blender/python/intern/bpy_app_timers.c +++ b/source/blender/python/intern/bpy_app_timers.c @@ -168,7 +168,7 @@ static struct PyModuleDef M_AppTimers_module_def = { NULL, /* m_doc */ 0, /* m_size */ M_AppTimers_methods, /* m_methods */ - NULL, /* m_reload */ + NULL, /* m_slots */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ diff --git a/source/blender/python/intern/bpy_gizmo_wrap.c b/source/blender/python/intern/bpy_gizmo_wrap.c index ad235e691c4..99720e7a1ba 100644 --- a/source/blender/python/intern/bpy_gizmo_wrap.c +++ b/source/blender/python/intern/bpy_gizmo_wrap.c @@ -150,7 +150,7 @@ void BPY_RNA_gizmo_wrapper(wmGizmoType *gzt, void *userdata) /* don't do translations here yet */ #if 0 - /* Use i18n context from rna_ext.srna if possible (py gizmogroups). */ + /* Use i18n context from rna_ext.srna if possible (py gizmo-groups). */ if (gt->rna_ext.srna) { RNA_def_struct_translation_context(gt->srna, RNA_struct_translation_context(gt->rna_ext.srna)); } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 939fa475344..3a095f4b9f3 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -11,6 +11,10 @@ #include <Python.h> #include <frameobject.h> +#ifdef WITH_PYTHON_MODULE +# include "pylifecycle.h" /* For `Py_Version`. */ +#endif + #include "MEM_guardedalloc.h" #include "CLG_log.h" @@ -585,6 +589,11 @@ void BPY_python_use_system_env(void) void BPY_python_backtrace(FILE *fp) { fputs("\n# Python backtrace\n", fp); + + /* Can happen in rare cases. */ + if (!_PyThreadState_UncheckedGet()) { + return; + } PyFrameObject *frame; if (!(frame = PyEval_GetFrame())) { return; @@ -763,7 +772,7 @@ static struct PyModuleDef bpy_proxy_def = { NULL, /* m_doc */ 0, /* m_size */ NULL, /* m_methods */ - NULL, /* m_reload */ + NULL, /* m_slots */ NULL, /* m_traverse */ NULL, /* m_clear */ bpy_module_free, /* m_free */ @@ -802,6 +811,50 @@ static void bpy_module_delay_init(PyObject *bpy_proxy) PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py)); } +/** + * Raise an error and return false if the Python version used to compile Blender + * isn't compatible with the interpreter loading the `bpy` module. + */ +static bool bpy_module_ensure_compatible_version(void) +{ + /* First check the Python version used matches the major version that Blender was built with. + * While this isn't essential, the error message in this case may be cryptic and misleading. + * NOTE: using `Py_LIMITED_API` would remove the need for this, in practice it's + * unlikely Blender will ever used the limited API though. */ +# if PY_VERSION_HEX >= 0x030b0000 /* Python 3.11 & newer. */ + const uint version_runtime = Py_Version; +# else + uint version_runtime; + { + uint version_runtime_major = 0, version_runtime_minor = 0; + const char *version_str = Py_GetVersion(); + if (sscanf(version_str, "%u.%u.", &version_runtime_major, &version_runtime_minor) != 2) { + /* Should never happen, raise an error to ensure this check never fails silently. */ + PyErr_Format(PyExc_ImportError, "Failed to extract the version from \"%s\"", version_str); + return false; + } + version_runtime = (version_runtime_major << 24) | (version_runtime_minor << 16); + } +# endif + + uint version_compile_major = PY_VERSION_HEX >> 24; + uint version_compile_minor = ((PY_VERSION_HEX & 0x00ff0000) >> 16); + uint version_runtime_major = version_runtime >> 24; + uint version_runtime_minor = ((version_runtime & 0x00ff0000) >> 16); + if ((version_compile_major != version_runtime_major) || + (version_compile_minor != version_runtime_minor)) { + PyErr_Format(PyExc_ImportError, + "The version of \"bpy\" was compiled with: " + "(%u.%u) is incompatible with: (%u.%u) used by the interpreter!", + version_compile_major, + version_compile_minor, + version_runtime_major, + version_runtime_minor); + return false; + } + return true; +} + static void dealloc_obj_dealloc(PyObject *self); static PyTypeObject dealloc_obj_Type; @@ -819,6 +872,10 @@ PyMODINIT_FUNC PyInit_bpy(void); PyMODINIT_FUNC PyInit_bpy(void) { + if (!bpy_module_ensure_compatible_version()) { + return NULL; /* The error has been set. */ + } + PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def); /* Problem: diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index 9754599eeed..f29a8d34359 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -108,7 +108,7 @@ static PyTypeObject bpy_lib_Type = { NULL, /* ternaryfunc tp_call; */ NULL, /* reprfunc tp_str; */ - /* will only use these if this is a subtype of a py class */ + /* Will only use these if this is a sub-type of a Python class. */ PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */ NULL, /* setattrofunc tp_setattro; */ diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 95879b02295..2db8c08cfd4 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -289,7 +289,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); /* Own so these don't move into global reports. */ - BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); + BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD | RPT_PRINT_HANDLED_BY_OWNER); #ifdef BPY_RELEASE_GIL /* release GIL, since a thread could be started from an operator diff --git a/source/blender/python/intern/bpy_path.c b/source/blender/python/intern/bpy_path.c index fbb47817389..f3a1a7cb1df 100644 --- a/source/blender/python/intern/bpy_path.c +++ b/source/blender/python/intern/bpy_path.c @@ -26,7 +26,7 @@ static struct PyModuleDef _bpy_path_module_def = { NULL, /* m_doc */ 0, /* m_size */ NULL, /* m_methods */ - NULL, /* m_reload */ + NULL, /* m_slots */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 179a0250688..07ce44f5f3b 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1397,7 +1397,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len); #ifdef USE_STRING_COERCE - /* Only file paths get special treatment, they may contain non utf-8 chars. */ + /* Only file paths get special treatment, they may contain non UTF-8 chars. */ if (subtype == PROP_BYTESTRING) { ret = PyBytes_FromStringAndSize(buf, buf_len); } @@ -2213,6 +2213,26 @@ static int pyrna_prop_collection_bool(BPy_PropertyRNA *self) } \ (void)0 +/** + * \param result: The result of calling a subscription operation on a collection (never NULL). + */ +static int pyrna_prop_collection_subscript_is_valid_or_error(const PyObject *value) +{ + if (value != Py_None) { + BLI_assert(BPy_StructRNA_Check(value)); + const BPy_StructRNA *value_pyrna = (const BPy_StructRNA *)value; + if (UNLIKELY(value_pyrna->ptr.type == NULL)) { + /* It's important to use a `TypeError` as that is what's returned when `__getitem__` is + * called on an object that doesn't support item access. */ + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not subscriptable (only iteration is supported)", + Py_TYPE(value)->tp_name); + return -1; + } + } + return 0; +} + /* Internal use only. */ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum) { @@ -2223,8 +2243,35 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s PYRNA_PROP_COLLECTION_ABS_INDEX(NULL); - if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) { - return pyrna_struct_CreatePyObject(&newptr); + if (RNA_property_collection_lookup_int_has_fn(self->prop)) { + if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) { + return pyrna_struct_CreatePyObject(&newptr); + } + } + else { + /* No callback defined, just iterate and find the nth item. */ + const int key = (int)keynum_abs; + PyObject *result = NULL; + bool found = false; + CollectionPropertyIterator iter; + RNA_property_collection_begin(&self->ptr, self->prop, &iter); + for (int i = 0; iter.valid; RNA_property_collection_next(&iter), i++) { + if (i == key) { + result = pyrna_struct_CreatePyObject(&iter.ptr); + found = true; + break; + } + } + /* It's important to end the iterator after `result` has been created + * so iterators may optionally invalidate items that were iterated over, see: T100286. */ + RNA_property_collection_end(&iter); + if (found) { + if (result && (pyrna_prop_collection_subscript_is_valid_or_error(result) == -1)) { + Py_DECREF(result); + result = NULL; /* The exception has been set. */ + } + return result; + } } const int len = RNA_property_collection_length(&self->ptr, self->prop); @@ -2306,8 +2353,45 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons PYRNA_PROP_CHECK_OBJ(self); - if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) { - return pyrna_struct_CreatePyObject(&newptr); + if (RNA_property_collection_lookup_string_has_fn(self->prop)) { + if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) { + return pyrna_struct_CreatePyObject(&newptr); + } + } + else { + /* No callback defined, just iterate and find the nth item. */ + const int keylen = strlen(keyname); + char name[256]; + int namelen; + PyObject *result = NULL; + bool found = false; + CollectionPropertyIterator iter; + RNA_property_collection_begin(&self->ptr, self->prop, &iter); + for (int i = 0; iter.valid; RNA_property_collection_next(&iter), i++) { + PropertyRNA *nameprop = RNA_struct_name_property(iter.ptr.type); + char *nameptr = RNA_property_string_get_alloc( + &iter.ptr, nameprop, name, sizeof(name), &namelen); + if ((keylen == namelen) && STREQ(nameptr, keyname)) { + found = true; + } + if ((char *)&name != nameptr) { + MEM_freeN(nameptr); + } + if (found) { + result = pyrna_struct_CreatePyObject(&iter.ptr); + break; + } + } + /* It's important to end the iterator after `result` has been created + * so iterators may optionally invalidate items that were iterated over, see: T100286. */ + RNA_property_collection_end(&iter); + if (found) { + if (result && (pyrna_prop_collection_subscript_is_valid_or_error(result) == -1)) { + Py_DECREF(result); + result = NULL; /* The exception has been set. */ + } + return result; + } } PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname); @@ -3990,7 +4074,7 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr) { const char *idname; - /* For looping over attrs and funcs. */ + /* For looping over attributes and functions. */ PointerRNA tptr; PropertyRNA *iterprop; @@ -5853,7 +5937,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat len = RNA_property_array_length(ptr, prop); } - /* Resolve the array from a new pytype. */ + /* Resolve the array from a new Python type. */ /* TODO(Kazanbas): make multi-dimensional sequences here. */ @@ -6403,7 +6487,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure) PyTypeObject pyrna_struct_meta_idprop_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct_meta_idprop", /* tp_name */ - /* NOTE: would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's. */ + /* NOTE: would be PyTypeObject, but sub-types of Type must be PyHeapTypeObject's. */ sizeof(PyHeapTypeObject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -7224,7 +7308,7 @@ static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dic if (base && base != srna) { // printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); py_base = pyrna_srna_Subtype(base); //, bpy_types_dict); - Py_DECREF(py_base); /* Srna owns, this is only to pass as an arg. */ + Py_DECREF(py_base); /* `srna` owns, this is only to pass as an argument. */ } if (py_base == NULL) { @@ -7784,7 +7868,7 @@ static struct PyModuleDef bpy_types_module_def = { bpy_types_module_doc, /* m_doc */ sizeof(struct BPy_TypesModule_State), /* m_size */ bpy_types_module_methods, /* m_methods */ - NULL, /* m_reload */ + NULL, /* m_slots */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ @@ -8651,10 +8735,10 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param else if (ret_len == 1) { err = pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, ""); - /* when calling operator funcs only gives Function.result with - * no line number since the func has finished calling on error, - * re-raise the exception with more info since it would be slow to - * create prefix on every call (when there are no errors) */ + /* When calling operator functions only gives `Function.result` with no line number + * since the function has finished calling on error, re-raise the exception with more + * information since it would be slow to create prefix on every call + * (when there are no errors). */ if (err == -1) { PyC_Err_Format_Prefix(PyExc_RuntimeError, "class %.200s, function %.200s: incompatible return value ", @@ -8762,7 +8846,7 @@ static void bpy_class_free(void *pyob_ptr) } /** - * \note This isn't essential to run on startup, since subtypes will lazy initialize. + * \note This isn't essential to run on startup, since sub-types will lazy initialize. * But keep running in debug mode so we get immediate notification of bad class hierarchy * or any errors in "bpy_types.py" at load time, so errors don't go unnoticed. */ diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 91fa0ea2c8d..d7778da6213 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -218,11 +218,13 @@ void pyrna_struct_type_extend_capi(struct StructRNA *srna, struct PyMethodDef *py_method, struct PyGetSetDef *py_getset); -/* called before stopping python */ +/* Called before stopping Python. */ + void pyrna_alloc_types(void); void pyrna_free_types(void); -/* primitive type conversion */ +/* Primitive type conversion. */ + int pyrna_py_to_array( PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix); int pyrna_py_to_array_index(PointerRNA *ptr, diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c index 8506ec97bc3..48ba028edf0 100644 --- a/source/blender/python/intern/bpy_rna_array.c +++ b/source/blender/python/intern/bpy_rna_array.c @@ -927,7 +927,7 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, /* just in case check */ len = RNA_property_multi_array_length(ptr, prop, arraydim); if (index >= len || index < 0) { - /* this shouldn't happen because higher level funcs must check for invalid index */ + /* This shouldn't happen because higher level functions must check for invalid index. */ CLOG_WARN(BPY_LOG_RNA, "invalid index %d for array with length=%d", index, len); PyErr_SetString(PyExc_IndexError, "out of range"); diff --git a/source/blender/python/intern/bpy_rna_data.c b/source/blender/python/intern/bpy_rna_data.c index cc0b4aa57d5..a3e865f4846 100644 --- a/source/blender/python/intern/bpy_rna_data.c +++ b/source/blender/python/intern/bpy_rna_data.c @@ -86,7 +86,7 @@ static PyTypeObject bpy_rna_data_context_Type = { NULL, /* ternaryfunc tp_call; */ NULL, /* reprfunc tp_str; */ - /* will only use these if this is a subtype of a py class */ + /* Will only use these if this is a sub-type of a Python class. */ NULL, /* getattrofunc tp_getattro; */ NULL, /* setattrofunc tp_setattro; */ diff --git a/source/blender/python/intern/bpy_rna_operator.c b/source/blender/python/intern/bpy_rna_operator.c index fd6cc93ed32..e0a4356dc18 100644 --- a/source/blender/python/intern/bpy_rna_operator.c +++ b/source/blender/python/intern/bpy_rna_operator.c @@ -84,7 +84,7 @@ PyDoc_STRVAR(BPY_rna_operator_poll_message_set_doc, " When message is callable, " "additional user defined positional arguments are passed to the message function.\n" "\n" - " :param message: The message or a function that returns the message.\n" + " :arg message: The message or a function that returns the message.\n" " :type message: string or a callable that returns a string or None.\n"); static PyObject *BPY_rna_operator_poll_message_set(PyObject *UNUSED(self), PyObject *args) diff --git a/source/blender/python/intern/bpy_rna_types_capi.c b/source/blender/python/intern/bpy_rna_types_capi.c index c3a07847aff..2b830eb9ffe 100644 --- a/source/blender/python/intern/bpy_rna_types_capi.c +++ b/source/blender/python/intern/bpy_rna_types_capi.c @@ -185,16 +185,16 @@ PyDoc_STRVAR( " It will be called every time the specified region in the space type will be drawn.\n" " Note: All arguments are positional only for now.\n" "\n" - " :param callback:\n" + " :arg callback:\n" " A function that will be called when the region is drawn.\n" " It gets the specified arguments as input.\n" " :type callback: function\n" - " :param args: Arguments that will be passed to the callback.\n" + " :arg args: Arguments that will be passed to the callback.\n" " :type args: tuple\n" - " :param region_type: The region type the callback draws in; usually ``WINDOW``. " + " :arg region_type: The region type the callback draws in; usually ``WINDOW``. " "(:class:`bpy.types.Region.type`)\n" " :type region_type: str\n" - " :param draw_type: Usually ``POST_PIXEL`` for 2D drawing and ``POST_VIEW`` for 3D drawing. " + " :arg draw_type: Usually ``POST_PIXEL`` for 2D drawing and ``POST_VIEW`` for 3D drawing. " "In some cases ``PRE_VIEW`` can be used. ``BACKDROP`` can be used for backdrops in the node " "editor.\n" " :type draw_type: str\n" @@ -206,9 +206,9 @@ PyDoc_STRVAR(pyrna_draw_handler_remove_doc, "\n" " Remove a draw handler that was added previously.\n" "\n" - " :param handler: The draw handler that should be removed.\n" + " :arg handler: The draw handler that should be removed.\n" " :type handler: object\n" - " :param region_type: Region type the callback was added to.\n" + " :arg region_type: Region type the callback was added to.\n" " :type region_type: str\n"); static struct PyMethodDef pyrna_space_methods[] = { diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c index 1f2458c752f..428263fd4c4 100644 --- a/source/blender/python/intern/bpy_traceback.c +++ b/source/blender/python/intern/bpy_traceback.c @@ -25,7 +25,7 @@ static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce) return PyBytes_AS_STRING(*coerce); } -/* copied from pythonrun.c, 3.10.0 */ +/* Copied from `pythonrun.c`, 3.10.0 */ _Py_static_string(PyId_string, "<string>"); static int parse_syntax_error(PyObject *err, diff --git a/source/blender/python/intern/bpy_utils_units.c b/source/blender/python/intern/bpy_utils_units.c index 1e5856a3285..075a68f31f9 100644 --- a/source/blender/python/intern/bpy_utils_units.c +++ b/source/blender/python/intern/bpy_utils_units.c @@ -90,7 +90,7 @@ static PyObject *py_structseq_from_strings(PyTypeObject *py_type, const char **str_iter; PyStructSequence_Field *desc; - /* initialize array */ + /* Initialize array. */ /* We really populate the contexts' fields here! */ for (str_iter = str_items, desc = py_sseq_desc->fields; *str_iter; str_iter++, desc++) { desc->name = (char *)*str_iter; @@ -101,7 +101,7 @@ static PyObject *py_structseq_from_strings(PyTypeObject *py_type, PyStructSequence_InitType(py_type, py_sseq_desc); - /* initialize pytype */ + /* Initialize the Python type. */ py_struct_seq = PyStructSequence_New(py_type); BLI_assert(py_struct_seq != NULL); diff --git a/source/blender/python/intern/stubs.c b/source/blender/python/intern/stubs.c index c29f9188eea..f860bdc36ee 100644 --- a/source/blender/python/intern/stubs.c +++ b/source/blender/python/intern/stubs.c @@ -25,7 +25,7 @@ void BPY_pyconstraint_exec(struct bPythonConstraint *con, void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTarget *ct) { } -int BPY_is_pyconstraint(struct Text *text) +bool BPY_is_pyconstraint(struct Text *text) { return 0; } |