diff options
Diffstat (limited to 'source/blender/python/intern/bpy_props.c')
-rw-r--r-- | source/blender/python/intern/bpy_props.c | 660 |
1 files changed, 423 insertions, 237 deletions
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index e61018865ab..d3eddff4b9a 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -37,7 +37,7 @@ #include "bpy_props.h" #include "bpy_rna.h" -#include "bpy_util.h" +#include "bpy_capi_utils.h" #include "BKE_idprop.h" @@ -50,15 +50,17 @@ #include "../generic/py_capi_utils.h" /* initial definition of callback slots we'll probably have more than 1 */ -#define BPY_DATA_CB_SLOT_SIZE 3 - -#define BPY_DATA_CB_SLOT_UPDATE 0 -#define BPY_DATA_CB_SLOT_GET 1 -#define BPY_DATA_CB_SLOT_SET 2 +enum { + BPY_DATA_CB_SLOT_UPDATE = 0, + BPY_DATA_CB_SLOT_GET = 1, + BPY_DATA_CB_SLOT_SET = 2, + BPY_DATA_CB_SLOT_POLL = 3, + BPY_DATA_CB_SLOT_SIZE = 4, +}; extern BPy_StructRNA *bpy_context_module; -static EnumPropertyItem property_flag_items[] = { +static const EnumPropertyItem property_flag_items[] = { {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""}, {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""}, {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animatable", ""}, @@ -72,7 +74,7 @@ static EnumPropertyItem property_flag_items[] = { "'TEXTEDIT_UPDATE'].\n" \ " :type options: set\n" \ -static EnumPropertyItem property_flag_enum_items[] = { +static const EnumPropertyItem property_flag_enum_items[] = { {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""}, {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""}, {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animatable", ""}, @@ -88,7 +90,7 @@ static EnumPropertyItem property_flag_enum_items[] = { /* XXX Keep in sync with rna_rna.c's rna_enum_property_subtype_items ??? * Currently it is not... */ -static EnumPropertyItem property_subtype_string_items[] = { +static const EnumPropertyItem property_subtype_string_items[] = { {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""}, {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""}, {PROP_FILENAME, "FILE_NAME", 0, "Filename", ""}, @@ -102,7 +104,7 @@ static EnumPropertyItem property_subtype_string_items[] = { " :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'BYTE_STRING', 'PASSWORD', 'NONE'].\n" \ " :type subtype: string\n" \ -static EnumPropertyItem property_subtype_number_items[] = { +static const EnumPropertyItem property_subtype_number_items[] = { {PROP_PIXEL, "PIXEL", 0, "Pixel", ""}, {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""}, {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""}, @@ -118,7 +120,7 @@ static EnumPropertyItem property_subtype_number_items[] = { " :arg subtype: Enumerator in ['PIXEL', 'UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" \ " :type subtype: string\n" \ -static EnumPropertyItem property_subtype_array_items[] = { +static const EnumPropertyItem property_subtype_array_items[] = { {PROP_COLOR, "COLOR", 0, "Color", ""}, {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""}, {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""}, @@ -178,22 +180,6 @@ static PyObject *pyrna_struct_as_instance(PointerRNA *ptr) return self; } -/* could be moved into bpy_utils */ -static void printf_func_error(PyObject *py_func) -{ - /* since we return to C code we can't leave the error */ - PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); - PyErr_Print(); - PyErr_Clear(); - - /* use py style error */ - fprintf(stderr, "File \"%s\", line %d, in %s\n", - _PyUnicode_AsString(f_code->co_filename), - f_code->co_firstlineno, - _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name) - ); -} - static void bpy_prop_assign_flag(PropertyRNA *prop, const int flag) { const int flag_mask = ((PROP_ANIMATABLE) & ~flag); @@ -230,7 +216,7 @@ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw) static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop) { PyGILState_STATE gilstate; - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -259,12 +245,12 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -279,7 +265,7 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -311,14 +297,14 @@ static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value = false; } else { - value = PyLong_AsLong(ret); + value = PyC_Long_AsI32(ret); if (value == -1 && PyErr_Occurred()) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value = false; } @@ -337,7 +323,7 @@ static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -370,12 +356,12 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA * Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -389,9 +375,54 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA * } } +static int bpy_prop_poll_cb(struct PointerRNA *self, PointerRNA candidate, struct PropertyRNA *prop) +{ + PyObject *py_self; + PyObject *py_candidate; + PyObject *py_func; + PyObject **py_data = RNA_property_py_data_get(prop); + PyObject *args; + PyObject *ret; + bool result; + const int is_write_ok = pyrna_write_check(); + PyGILState_STATE gilstate = PyGILState_Ensure(); + + BLI_assert(self != NULL); + + py_self = pyrna_struct_as_instance(self); + py_candidate = pyrna_struct_as_instance(&candidate); + py_func = py_data[BPY_DATA_CB_SLOT_POLL]; + + if (!is_write_ok) + pyrna_write_set(true); + + args = PyTuple_New(2); + PyTuple_SET_ITEM(args, 0, py_self); + PyTuple_SET_ITEM(args, 1, py_candidate); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + PyC_Err_PrintWithFunc(py_func); + result = false; + } + else { + result = PyObject_IsTrue(ret); + Py_DECREF(ret); + } + + PyGILState_Release(gilstate); + if (!is_write_ok) + pyrna_write_set(false); + + return result; +} + static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -423,14 +454,14 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); for (i = 0; i < len; ++i) values[i] = false; } else { if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") == -1) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); for (i = 0; i < len; ++i) values[i] = false; @@ -452,7 +483,7 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -480,24 +511,20 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct Propert self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); - py_values = PyC_FromArray(values, len, &PyBool_Type, false, "BoolVectorProperty set"); - if (!py_values) { - printf_func_error(py_func); - } - else - PyTuple_SET_ITEM(args, 1, py_values); + py_values = PyC_Tuple_PackArray_I32FromBool(values, len); + PyTuple_SET_ITEM(args, 1, py_values); ret = PyObject_CallObject(py_func, args); Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -513,7 +540,7 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct Propert static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -545,14 +572,14 @@ static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value = 0.0f; } else { - value = PyLong_AsLong(ret); + value = PyC_Long_AsI32(ret); if (value == -1 && PyErr_Occurred()) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value = 0; } @@ -571,7 +598,7 @@ static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -604,12 +631,12 @@ static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -625,7 +652,7 @@ static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -657,14 +684,14 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); for (i = 0; i < len; ++i) values[i] = 0; } else { if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") == -1) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); for (i = 0; i < len; ++i) values[i] = 0; @@ -686,7 +713,7 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -714,24 +741,20 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); - py_values = PyC_FromArray(values, len, &PyLong_Type, false, "IntVectorProperty set"); - if (!py_values) { - printf_func_error(py_func); - } - else - PyTuple_SET_ITEM(args, 1, py_values); + py_values = PyC_Tuple_PackArray_I32(values, len); + PyTuple_SET_ITEM(args, 1, py_values); ret = PyObject_CallObject(py_func, args); Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -747,7 +770,7 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -779,14 +802,14 @@ static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value = 0.0f; } else { value = PyFloat_AsDouble(ret); if (value == -1.0f && PyErr_Occurred()) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value = 0.0f; } @@ -805,7 +828,7 @@ static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float value) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -838,12 +861,12 @@ static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pr Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -859,7 +882,7 @@ static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pr static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -891,14 +914,14 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); for (i = 0; i < len; ++i) values[i] = 0.0f; } else { if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") == -1) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); for (i = 0; i < len; ++i) values[i] = 0.0f; @@ -920,7 +943,7 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -948,24 +971,20 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyR self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); - py_values = PyC_FromArray(values, len, &PyFloat_Type, false, "FloatVectorProperty set"); - if (!py_values) { - printf_func_error(py_func); - } - else - PyTuple_SET_ITEM(args, 1, py_values); + py_values = PyC_Tuple_PackArray_F32(values, len); + PyTuple_SET_ITEM(args, 1, py_values); ret = PyObject_CallObject(py_func, args); Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -981,7 +1000,7 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyR static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -1012,14 +1031,14 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value[0] = '\0'; } else if (!PyUnicode_Check(ret)) { PyErr_Format(PyExc_TypeError, "return value must be a string, not %.200s", Py_TYPE(ret)->tp_name); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value[0] = '\0'; Py_DECREF(ret); } @@ -1040,7 +1059,7 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -1072,14 +1091,14 @@ static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); length = 0; } else if (!PyUnicode_Check(ret)) { PyErr_Format(PyExc_TypeError, "return value must be a string, not %.200s", Py_TYPE(ret)->tp_name); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); length = 0; Py_DECREF(ret); } @@ -1102,7 +1121,7 @@ static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -1132,7 +1151,7 @@ static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *p py_value = PyUnicode_FromString(value); if (!py_value) { PyErr_SetString(PyExc_ValueError, "the return value must be a string"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else PyTuple_SET_ITEM(args, 1, py_value); @@ -1142,12 +1161,12 @@ static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *p Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -1163,7 +1182,7 @@ static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *p static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -1195,14 +1214,14 @@ static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value = RNA_property_enum_get_default(ptr, prop); } else { - value = PyLong_AsLong(ret); + value = PyC_Long_AsI32(ret); if (value == -1 && PyErr_Occurred()) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); value = RNA_property_enum_get_default(ptr, prop); } @@ -1221,7 +1240,7 @@ static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) { - PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject **py_data = RNA_property_py_data_get(prop); PyObject *py_func; PyObject *args; PyObject *self; @@ -1254,12 +1273,12 @@ static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pro Py_DECREF(args); if (ret == NULL) { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } else { if (ret != Py_None) { PyErr_SetString(PyExc_ValueError, "the return value must be None"); - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); } Py_DECREF(ret); @@ -1300,7 +1319,7 @@ static size_t strswapbufcpy(char *buf, const char **orig) static int icon_id_from_name(const char *name) { - EnumPropertyItem *item; + const EnumPropertyItem *item; int id; if (name[0]) { @@ -1314,7 +1333,7 @@ static int icon_id_from_name(const char *name) return 0; } -static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const bool is_enum_flag) +static const EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const bool is_enum_flag) { EnumPropertyItem *items; PyObject *item; @@ -1470,7 +1489,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i return items; } -static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free) +static const EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free) { PyGILState_STATE gilstate; @@ -1479,7 +1498,7 @@ static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA * PyObject *args; PyObject *items; /* returned from the function call */ - EnumPropertyItem *eitems = NULL; + const EnumPropertyItem *eitems = NULL; int err = 0; if (C) { @@ -1537,7 +1556,7 @@ static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA * *r_free = true; } else { - printf_func_error(py_func); + PyC_Err_PrintWithFunc(py_func); eitems = DummyRNA_NULL_items; } @@ -1598,6 +1617,16 @@ static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject * } } +static void bpy_prop_callback_assign_pointer(struct PropertyRNA *prop, PyObject *poll_cb) +{ + if (poll_cb && poll_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + RNA_def_property_poll_runtime(prop, (void *) bpy_prop_poll_cb); + py_data[BPY_DATA_CB_SLOT_POLL] = poll_cb; + } +} + static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) { BooleanPropertyGetFunc rna_get_cb = NULL; @@ -1829,7 +1858,22 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *ge #_func"(options={ ...}):"))) \ { \ return NULL; \ - } (void)0 + } \ + { \ + const EnumPropertyItem *tag_defines = RNA_struct_property_tag_defines(srna); \ + if (py_tags && !tag_defines) { \ + PyErr_Format(PyExc_TypeError, \ + #_func"(): property-tags not available for '%s'", \ + RNA_struct_identifier(srna)); \ + return NULL; \ + } \ + if (UNLIKELY(py_tags && pyrna_set_to_enum_bitfield( \ + tag_defines, py_tags, \ + &prop_tags, #_func"(tags={ ...}):"))) \ + { \ + return NULL; \ + } \ + }(void)0 #define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \ BPY_PROPDEF_CHECK(_func, _property_flag_items); \ @@ -1893,6 +1937,11 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *ge " *Warning* there are no safety checks to avoid infinite recursion.\n" \ " :type update: function\n" \ +#define BPY_PROPDEF_POLL_DOC \ +" :arg poll: function to be called to determine whether an item is valid for this property.\n" \ +" The function must take 2 values (self, object) and return Bool.\n" \ +" :type poll: function\n" \ + #define BPY_PROPDEF_GET_DOC \ " :arg get: Function to be called when this value is 'read',\n" \ " This function must take 1 value (self) and return the value of the property.\n" \ @@ -1904,9 +1953,13 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *ge " :type set: function\n" \ #define BPY_PROPDEF_TYPE_DOC \ -" :arg type: A subclass of :class:`bpy.types.PropertyGroup`.\n" \ +" :arg type: A subclass of :class:`bpy.types.PropertyGroup` or :class:`bpy.types.ID`.\n" \ " :type type: class\n" \ +#define BPY_PROPDEF_TAGS_DOC \ +" :arg tags: Enumerator of tags that are defined by parent class.\n" \ +" :type tags: set\n" \ + #if 0 static int bpy_struct_id_used(StructRNA *srna, char *identifier) { @@ -1925,6 +1978,7 @@ PyDoc_STRVAR(BPy_BoolProperty_doc, "description=\"\", " "default=False, " "options={'ANIMATABLE'}, " + "tags={}, " "subtype='NONE', " "update=None, " "get=None, " @@ -1935,6 +1989,7 @@ PyDoc_STRVAR(BPy_BoolProperty_doc, BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_DOC BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC @@ -1947,26 +2002,32 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) BPY_PROPDEF_HEAD(BoolProperty); if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; bool def = false; PropertyRNA *prop; PyObject *pyopts = NULL; int opts = 0; + int prop_tags = 0; const char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssO&O!sOOO:BoolProperty", - (char **)kwlist, &id, &id_len, - &name, &description, PyC_ParseBool, &def, - &PySet_Type, &pyopts, &pysubtype, - &update_cb, &get_cb, &set_cb)) + PyObject *py_tags = NULL; + + static const char *_keywords[] = { + "attr", "name", "description", "default", + "options", "tags", "subtype", + "update", "get", "set", NULL, + }; + static _PyArg_Parser _parser = {"s#|ssO&O!O!sOOO:BoolProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &name, &description, PyC_ParseBool, &def, + &PySet_Type, &pyopts, &PySet_Type, &py_tags, &pysubtype, + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -1987,6 +2048,9 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_boolean_default(prop, def); RNA_def_property_ui_text(prop, name ? name : id, description); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } @@ -2003,6 +2067,7 @@ PyDoc_STRVAR(BPy_BoolVectorProperty_doc, "description=\"\", " "default=(False, False, False), " "options={'ANIMATABLE'}, " + "tags={}, " "subtype='NONE', " "size=3, " "update=None, " @@ -2016,6 +2081,7 @@ BPY_PROPDEF_DESC_DOC " :arg default: sequence of booleans the length of *size*.\n" " :type default: sequence\n" BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_ARRAY_DOC BPY_PROPDEF_VECSIZE_DOC BPY_PROPDEF_UPDATE_DOC @@ -2029,8 +2095,6 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject BPY_PROPDEF_HEAD(BoolVectorProperty); if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "options", "subtype", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int def[PYRNA_STACK_ARRAY] = {0}; @@ -2039,18 +2103,27 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject PyObject *pydef = NULL; PyObject *pyopts = NULL; int opts = 0; + int prop_tags = 0; const char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOO!siOOO:BoolVectorProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &pydef, - &PySet_Type, &pyopts, &pysubtype, &size, - &update_cb, &get_cb, &set_cb)) + PyObject *py_tags = NULL; + + static const char *_keywords[] = { + "attr", "name", "description", "default", + "options", "tags", "subtype", "size", + "update", "get", "set", NULL, + }; + static _PyArg_Parser _parser = {"s#|ssOO!O!siOOO:BoolVectorProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &name, &description, &pydef, + &PySet_Type, &pyopts, &PySet_Type, &py_tags, + &pysubtype, &size, + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -2083,6 +2156,9 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject if (pydef) RNA_def_property_boolean_array_default(prop, def); RNA_def_property_ui_text(prop, name ? name : id, description); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } @@ -2102,6 +2178,7 @@ PyDoc_STRVAR(BPy_IntProperty_doc, "soft_min=-2**31, soft_max=2**31-1, " "step=1, " "options={'ANIMATABLE'}, " + "tags={}, " "subtype='NONE', " "update=None, " "get=None, " @@ -2121,6 +2198,7 @@ BPY_PROPDEF_NUM_SOFTMIN_DOC " :type soft_max: int\n" BPY_PROPDEF_INT_STEP_DOC BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_DOC BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC @@ -2133,28 +2211,34 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) BPY_PROPDEF_HEAD(IntProperty); if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", - "step", "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0; PropertyRNA *prop; PyObject *pyopts = NULL; int opts = 0; + int prop_tags = 0; const char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssiiiiiiO!sOOO:IntProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &def, - &min, &max, &soft_min, &soft_max, - &step, &PySet_Type, &pyopts, &pysubtype, - &update_cb, &get_cb, &set_cb)) + PyObject *py_tags = NULL; + + static const char *_keywords[] = { + "attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "options", "tags", "subtype", + "update", "get", "set", NULL, + }; + static _PyArg_Parser _parser = {"s#|ssiiiiiiO!O!sOOO:IntProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &name, &description, &def, + &min, &max, &soft_min, &soft_max, + &step, &PySet_Type, &pyopts, &PySet_Type, &py_tags, &pysubtype, + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -2177,6 +2261,9 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_range(prop, min, max); RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } @@ -2195,6 +2282,7 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc, "soft_max=2**31-1, " "step=1, " "options={'ANIMATABLE'}, " + "tags={}, " "subtype='NONE', " "size=3, " "update=None, " @@ -2217,6 +2305,7 @@ BPY_PROPDEF_NUM_SOFTMAX_DOC " :type soft_max: int\n" BPY_PROPDEF_INT_STEP_DOC BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_ARRAY_DOC BPY_PROPDEF_VECSIZE_DOC BPY_PROPDEF_UPDATE_DOC @@ -2230,9 +2319,6 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject BPY_PROPDEF_HEAD(IntVectorProperty); if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", - "step", "options", "subtype", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1; @@ -2242,20 +2328,29 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject PyObject *pydef = NULL; PyObject *pyopts = NULL; int opts = 0; + int prop_tags = 0; const char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOiiiiiO!siOOO:IntVectorProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &pydef, - &min, &max, &soft_min, &soft_max, - &step, &PySet_Type, &pyopts, - &pysubtype, &size, - &update_cb, &get_cb, &set_cb)) + PyObject *py_tags = NULL; + + static const char *_keywords[] = { + "attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "options", "tags", "subtype", "size", + "update", "get", "set", NULL, + }; + static _PyArg_Parser _parser = {"s#|ssOiiiiiO!O!siOOO:IntVectorProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &name, &description, &pydef, + &min, &max, &soft_min, &soft_max, + &step, &PySet_Type, &pyopts, &PySet_Type, &py_tags, + &pysubtype, &size, + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -2289,6 +2384,9 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject RNA_def_property_ui_text(prop, name ? name : id, description); RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } @@ -2309,6 +2407,7 @@ PyDoc_STRVAR(BPy_FloatProperty_doc, "step=3, " "precision=2, " "options={'ANIMATABLE'}, " + "tags={}, " "subtype='NONE', " "unit='NONE', " "update=None, " @@ -2330,6 +2429,7 @@ BPY_PROPDEF_NUM_SOFTMAX_DOC BPY_PROPDEF_FLOAT_STEP_DOC BPY_PROPDEF_FLOAT_PREC_DOC BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_DOC BPY_PROPDEF_UNIT_DOC BPY_PROPDEF_UPDATE_DOC @@ -2343,10 +2443,6 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) BPY_PROPDEF_HEAD(FloatProperty); if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", - "step", "precision", "options", "subtype", - "unit", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f; @@ -2354,6 +2450,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) PropertyRNA *prop; PyObject *pyopts = NULL; int opts = 0; + int prop_tags = 0; const char *pysubtype = NULL; int subtype = PROP_NONE; const char *pyunit = NULL; @@ -2361,15 +2458,23 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssffffffiO!ssOOO:FloatProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &def, - &min, &max, &soft_min, &soft_max, - &step, &precision, &PySet_Type, - &pyopts, &pysubtype, &pyunit, - &update_cb, &get_cb, &set_cb)) + PyObject *py_tags = NULL; + + static const char *_keywords[] = { + "attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "precision", "options", "tags", "subtype", + "unit", "update", "get", "set", NULL, + }; + static _PyArg_Parser _parser = {"s#|ssffffffiO!O!ssOOO:FloatProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &name, &description, &def, + &min, &max, &soft_min, &soft_max, + &step, &precision, &PySet_Type, + &pyopts, &PySet_Type, &py_tags, &pysubtype, &pyunit, + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -2397,6 +2502,9 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_ui_text(prop, name ? name : id, description); RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } @@ -2416,6 +2524,7 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc, "step=3, " "precision=2, " "options={'ANIMATABLE'}, " + "tags={}, " "subtype='NONE', " "unit='NONE', " "size=3, " @@ -2438,6 +2547,7 @@ BPY_PROPDEF_NUM_SOFTMIN_DOC BPY_PROPDEF_NUM_SOFTMAX_DOC " :type soft_max: float\n" BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_FLOAT_STEP_DOC BPY_PROPDEF_FLOAT_PREC_DOC BPY_PROPDEF_SUBTYPE_ARRAY_DOC @@ -2454,10 +2564,6 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec BPY_PROPDEF_HEAD(FloatVectorProperty); if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", - "step", "precision", "options", "subtype", - "unit", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3; @@ -2467,6 +2573,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec PyObject *pydef = NULL; PyObject *pyopts = NULL; int opts = 0; + int prop_tags = 0; const char *pysubtype = NULL; int subtype = PROP_NONE; const char *pyunit = NULL; @@ -2474,15 +2581,23 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOfffffiO!ssiOOO:FloatVectorProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &pydef, - &min, &max, &soft_min, &soft_max, - &step, &precision, &PySet_Type, - &pyopts, &pysubtype, &pyunit, &size, - &update_cb, &get_cb, &set_cb)) + PyObject *py_tags = NULL; + + static const char *_keywords[] = { + "attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "precision", "options", "tags", "subtype", + "unit", "size", "update", "get", "set", NULL, + }; + static _PyArg_Parser _parser = {"s#|ssOfffffiO!O!ssiOOO:FloatVectorProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &name, &description, &pydef, + &min, &max, &soft_min, &soft_max, + &step, &precision, &PySet_Type, + &pyopts, &PySet_Type, &py_tags, &pysubtype, &pyunit, &size, + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -2521,6 +2636,9 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec RNA_def_property_ui_text(prop, name ? name : id, description); RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } @@ -2537,6 +2655,7 @@ PyDoc_STRVAR(BPy_StringProperty_doc, "default=\"\", " "maxlen=0, " "options={'ANIMATABLE'}, " + "tags={}, " "subtype='NONE', " "update=None, " "get=None, " @@ -2551,6 +2670,7 @@ BPY_PROPDEF_DESC_DOC " :arg maxlen: maximum length of the string.\n" " :type maxlen: int\n" BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_STRING_DOC BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC @@ -2563,26 +2683,32 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw BPY_PROPDEF_HEAD(StringProperty); if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "maxlen", "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = "", *def = ""; int id_len; int maxlen = 0; PropertyRNA *prop; PyObject *pyopts = NULL; int opts = 0; + int prop_tags = 0; const char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|sssiO!sOOO:StringProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &def, - &maxlen, &PySet_Type, &pyopts, &pysubtype, - &update_cb, &get_cb, &set_cb)) + PyObject *py_tags = NULL; + + static const char *_keywords[] = { + "attr", "name", "description", "default", + "maxlen", "options", "tags", "subtype", + "update", "get", "set", NULL, + }; + static _PyArg_Parser _parser = {"s#|sssiO!O!sOOO:StringProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &name, &description, &def, + &maxlen, &PySet_Type, &pyopts, &PySet_Type, &py_tags, &pysubtype, + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -2604,6 +2730,9 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw if (def && def[0]) RNA_def_property_string_default(prop, def); RNA_def_property_ui_text(prop, name ? name : id, description); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } @@ -2620,6 +2749,7 @@ PyDoc_STRVAR(BPy_EnumProperty_doc, "description=\"\", " "default=None, " "options={'ANIMATABLE'}, " + "tags={}, " "update=None, " "get=None, " "set=None)\n" @@ -2637,7 +2767,8 @@ PyDoc_STRVAR(BPy_EnumProperty_doc, " :icon: An icon string identifier or integer icon value\n" " (e.g. returned by :class:`bpy.types.UILayout.icon`)\n" " :number: Unique value used as the identifier for this item (stored in file data).\n" -" Use when the identifier may need to change.\n" +" Use when the identifier may need to change. If the *ENUM_FLAG* option is used,\n" +" the values are bitmasks and should be powers of two.\n" "\n" " When an item only contains 4 items they define ``(identifier, name, description, number)``.\n" "\n" @@ -2660,6 +2791,7 @@ BPY_PROPDEF_DESC_DOC " (i.e. if a callback function is given as *items* parameter).\n" " :type default: string or set\n" BPY_PROPDEF_OPTIONS_ENUM_DOC +BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC @@ -2671,28 +2803,33 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) BPY_PROPDEF_HEAD(EnumProperty); if (srna) { - static const char *kwlist[] = {"attr", "items", "name", "description", "default", - "options", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; PyObject *def = NULL; int id_len; int defvalue = 0; PyObject *items, *items_fast; - EnumPropertyItem *eitems; + const EnumPropertyItem *eitems; PropertyRNA *prop; PyObject *pyopts = NULL; int opts = 0; + int prop_tags = 0; bool is_itemf = false; PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#O|ssOO!OOO:EnumProperty", - (char **)kwlist, &id, &id_len, - &items, &name, &description, - &def, &PySet_Type, &pyopts, - &update_cb, &get_cb, &set_cb)) + PyObject *py_tags = NULL; + + static const char *_keywords[] = { + "attr", "items", "name", "description", "default", + "options", "tags", "update", "get", "set", NULL, + }; + static _PyArg_Parser _parser = {"s#O|ssOO!O!OOO:EnumProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &items, &name, &description, + &def, &PySet_Type, &pyopts, &PySet_Type, &py_tags, + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -2754,6 +2891,9 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description); else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } @@ -2766,13 +2906,13 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) * otherwise if this is a generator it may free the strings before we copy them */ Py_DECREF(items_fast); - MEM_freeN(eitems); + MEM_freeN((void *)eitems); } } Py_RETURN_NONE; } -static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix) +StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix) { StructRNA *srna; @@ -2782,25 +2922,18 @@ static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix PyObject *msg = PyC_ExceptionBuffer(); const char *msg_char = _PyUnicode_AsString(msg); PyErr_Format(PyExc_TypeError, - "%.200s expected an RNA type derived from PropertyGroup, failed with: %s", + "%.200s expected an RNA type, failed with: %s", error_prefix, msg_char); Py_DECREF(msg); } else { PyErr_Format(PyExc_TypeError, - "%.200s expected an RNA type derived from PropertyGroup, failed with type '%s'", + "%.200s expected an RNA type, failed with type '%s'", error_prefix, Py_TYPE(value)->tp_name); } return NULL; } - if (!RNA_struct_is_a(srna, &RNA_PropertyGroup)) { - PyErr_Format(PyExc_TypeError, - "%.200s expected an RNA type derived from PropertyGroup", - error_prefix); - return NULL; - } - return srna; } @@ -2809,6 +2942,8 @@ PyDoc_STRVAR(BPy_PointerProperty_doc, "name=\"\", " "description=\"\", " "options={'ANIMATABLE'}, " + "tags={}, " + "poll=None, " "update=None)\n" "\n" " Returns a new pointer property definition.\n" @@ -2817,50 +2952,75 @@ BPY_PROPDEF_TYPE_DOC BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC +BPY_PROPDEF_POLL_DOC BPY_PROPDEF_UPDATE_DOC ); -static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) +PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) { StructRNA *srna; BPY_PROPDEF_HEAD(PointerProperty); if (srna) { - static const char *kwlist[] = {"attr", "type", "name", "description", "options", "update", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; PropertyRNA *prop; StructRNA *ptype; PyObject *type = Py_None; PyObject *pyopts = NULL; + PyObject *py_tags = NULL; int opts = 0; - PyObject *update_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#O|ssO!O:PointerProperty", - (char **)kwlist, &id, &id_len, - &type, &name, &description, - &PySet_Type, &pyopts, - &update_cb)) + int prop_tags = 0; + PyObject *update_cb = NULL, *poll_cb = NULL; + + static const char *_keywords[] = { + "attr", "type", "name", "description", "options", + "tags", "poll", "update", NULL, + }; + static _PyArg_Parser _parser = {"s#O|ssO!O!OO:PointerProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &type, &name, &description, + &PySet_Type, &pyopts, &PySet_Type, &py_tags, + &poll_cb, &update_cb)) { return NULL; } BPY_PROPDEF_CHECK(PointerProperty, property_flag_items); - ptype = pointer_type_from_py(type, "PointerProperty(...):"); + ptype = pointer_type_from_py(type, "PointerProperty(...)"); if (!ptype) return NULL; - + if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup) && !RNA_struct_is_ID(ptype)) { + PyErr_Format(PyExc_TypeError, + "PointerProperty(...) expected an RNA type derived from %.200s or %.200s", + RNA_struct_ui_name(&RNA_ID), RNA_struct_ui_name(&RNA_PropertyGroup)); + return NULL; + } if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { return NULL; } - + if (bpy_prop_callback_check(poll_cb, "poll", 2) == -1) { + return NULL; + } prop = RNA_def_pointer_runtime(srna, id, ptype, name ? name : id, description); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } + + if (RNA_struct_idprops_contains_datablock(ptype)) { + if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) { + RNA_def_struct_flag(srna, STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES); + } + } bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_pointer(prop, poll_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -2870,7 +3030,8 @@ PyDoc_STRVAR(BPy_CollectionProperty_doc, ".. function:: CollectionProperty(type=None, " "name=\"\", " "description=\"\", " - "options={'ANIMATABLE'})\n" + "options={'ANIMATABLE'}, " + "tags={})\n" "\n" " Returns a new collection property definition.\n" "\n" @@ -2878,28 +3039,35 @@ BPY_PROPDEF_TYPE_DOC BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_OPTIONS_DOC +BPY_PROPDEF_TAGS_DOC ); -static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) +PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) { StructRNA *srna; BPY_PROPDEF_HEAD(CollectionProperty); if (srna) { - static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL}; - const char *id = NULL, *name = NULL, *description = ""; int id_len; + const char *id = NULL, *name = NULL, *description = ""; PropertyRNA *prop; StructRNA *ptype; PyObject *type = Py_None; PyObject *pyopts = NULL; + PyObject *py_tags = NULL; int opts = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#O|ssO!:CollectionProperty", - (char **)kwlist, &id, &id_len, - &type, &name, &description, - &PySet_Type, &pyopts)) + int prop_tags = 0; + + static const char *_keywords[] = { + "attr", "type", "name", "description", + "options", "tags", NULL, + }; + static _PyArg_Parser _parser = {"s#O|ssO!O!:CollectionProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id, &id_len, + &type, &name, &description, + &PySet_Type, &pyopts, &PySet_Type, &py_tags)) { return NULL; } @@ -2910,17 +3078,33 @@ static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject if (!ptype) return NULL; + if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup)) { + PyErr_Format(PyExc_TypeError, + "CollectionProperty(...) expected an RNA type derived from %.200s", + RNA_struct_ui_name(&RNA_ID), RNA_struct_ui_name(&RNA_PropertyGroup)); + return NULL; + } + prop = RNA_def_collection_runtime(srna, id, ptype, name ? name : id, description); + if (py_tags) { + RNA_def_property_tags(prop, prop_tags); + } if (pyopts) { bpy_prop_assign_flag(prop, opts); } + + if (RNA_struct_idprops_contains_datablock(ptype)) { + if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) { + RNA_def_struct_flag(srna, STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES); + } + } RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; } PyDoc_STRVAR(BPy_RemoveProperty_doc, -".. function:: RemoveProperty(cls, attr="")\n" +".. function:: RemoveProperty(cls, attr)\n" "\n" " Removes a dynamically defined property.\n" "\n" @@ -2958,13 +3142,15 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw return NULL; } else { - static const char *kwlist[] = {"attr", NULL}; - const char *id = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s:RemoveProperty", - (char **)kwlist, &id)) + static const char *_keywords[] = { + "attr", NULL, + }; + static _PyArg_Parser _parser = {"s:RemoveProperty", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast( + args, kw, &_parser, + &id)) { return NULL; } |