diff options
Diffstat (limited to 'source/blender/python/intern/bpy_props.c')
-rw-r--r-- | source/blender/python/intern/bpy_props.c | 326 |
1 files changed, 165 insertions, 161 deletions
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 104027c0997..ada8736158c 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -26,7 +26,9 @@ #include "bpy_rna.h" #include "bpy_util.h" -#include "BKE_utildefines.h" +#include "BLI_utildefines.h" + + #include "RNA_define.h" /* for defining our own rna */ #include "RNA_enum_types.h" @@ -40,6 +42,12 @@ EnumPropertyItem property_flag_items[] = { {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""}, {0, NULL, 0, NULL, NULL}}; +EnumPropertyItem property_flag_enum_items[] = { + {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""}, + {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""}, + {PROP_ENUM_FLAG, "ENUM_FLAG", 0, "Enum Flag", ""}, + {0, NULL, 0, NULL, NULL}}; + /* subtypes */ EnumPropertyItem property_subtype_string_items[] = { {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""}, @@ -132,6 +140,27 @@ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw) return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \ } \ +/* terse macros for error checks shared between all funcs cant use function + * calls because of static strins passed to pyrna_set_to_enum_bitfield */ +#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \ + if(id_len >= MAX_IDPROP_NAME) { \ + PyErr_Format(PyExc_TypeError, #_func"(): '%.200s' too long, max length is %d", id, MAX_IDPROP_NAME-1); \ + return NULL; \ + } \ + if(RNA_def_property_free_identifier(srna, id) == -1) { \ + PyErr_Format(PyExc_TypeError, #_func"(): '%s' is defined as a non-dynamic type", id); \ + return NULL; \ + } \ + if(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, pyopts, &opts, #_func"(options={...}):")) \ + return NULL; \ + +#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \ + BPY_PROPDEF_CHECK(_func, _property_flag_items) \ + if(pysubtype && RNA_enum_value_from_id(_subtype, pysubtype, &subtype)==0) { \ + PyErr_Format(PyExc_TypeError, #_func"(subtype='%s'): invalid subtype", pysubtype); \ + return NULL; \ + } \ + #if 0 static int bpy_struct_id_used(StructRNA *srna, char *identifier) @@ -162,8 +191,9 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) BPY_PROPDEF_HEAD(BoolProperty) if(srna) { - static char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", NULL}; - char *id=NULL, *name="", *description=""; + static const char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", NULL}; + const char *id=NULL, *name="", *description=""; + int id_len; int def=0; PropertyRNA *prop; PyObject *pyopts= NULL; @@ -171,23 +201,11 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) char *pysubtype= NULL; int subtype= PROP_NONE; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiO!s:BoolProperty", (char **)kwlist, &id, &name, &description, &def, &PySet_Type, &pyopts, &pysubtype)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssiO!s:BoolProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &PySet_Type, &pyopts, &pysubtype)) return NULL; - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "BoolProperty(): '%s' is defined as a non-dynamic type.", id); - return NULL; - } + BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items) - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "BoolProperty(options={...}):")) - return NULL; - - if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "BoolProperty(subtype='%s'): invalid subtype.", pysubtype); - return NULL; - } - - // prop= RNA_def_boolean(srna, id, def, name, description); prop= RNA_def_property(srna, id, PROP_BOOLEAN, subtype); RNA_def_property_boolean_default(prop, def); RNA_def_property_ui_text(prop, name, description); @@ -219,7 +237,8 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject if(srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", "size", NULL}; - char *id=NULL, *name="", *description=""; + const char *id=NULL, *name="", *description=""; + int id_len; int def[PYRNA_STACK_ARRAY]={0}; int size=3; PropertyRNA *prop; @@ -229,24 +248,13 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject char *pysubtype= NULL; int subtype= PROP_NONE; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOO!si:BoolVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &PySet_Type, &pyopts, &pysubtype, &size)) - return NULL; - - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "BoolVectorProperty(): '%s' is defined as a non-dynamic type.", id); + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOO!si:BoolVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &PySet_Type, &pyopts, &pysubtype, &size)) return NULL; - } - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "BoolVectorProperty(options={...}):")) - return NULL; - - if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "BoolVectorProperty(subtype='%s'): invalid subtype.", pysubtype); - return NULL; - } + BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items) if(size < 1 || size > PYRNA_STACK_ARRAY) { - PyErr_Format(PyExc_TypeError, "BoolVectorProperty(size=%d): size must be between 0 and %d.", size, PYRNA_STACK_ARRAY); + PyErr_Format(PyExc_TypeError, "BoolVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size); return NULL; } @@ -286,7 +294,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) if(srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", NULL}; - char *id=NULL, *name="", *description=""; + const char *id=NULL, *name="", *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; @@ -294,21 +303,10 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) char *pysubtype= NULL; int subtype= PROP_NONE; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiiiiO!s:IntProperty", (char **)kwlist, &id, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssiiiiiiO!s:IntProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype)) return NULL; - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "IntProperty(): '%s' is defined as a non-dynamic type.", id); - return NULL; - } - - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "IntProperty(options={...}):")) - return NULL; - - if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "IntProperty(subtype='%s'): invalid subtype.", pysubtype); - return NULL; - } + BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items) prop= RNA_def_property(srna, id, PROP_INT, subtype); RNA_def_property_int_default(prop, def); @@ -342,7 +340,8 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject if(srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", NULL}; - char *id=NULL, *name="", *description=""; + const char *id=NULL, *name="", *description=""; + int id_len; int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def[PYRNA_STACK_ARRAY]={0}; int size=3; PropertyRNA *prop; @@ -352,24 +351,13 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject char *pysubtype= NULL; int subtype= PROP_NONE; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOiiiiiO!si:IntVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype, &size)) - return NULL; - - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "IntVectorProperty(): '%s' is defined as a non-dynamic type.", id); - return NULL; - } - - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "IntVectorProperty(options={...}):")) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOiiiiiO!si:IntVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype, &size)) return NULL; - if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "IntVectorProperty(subtype='%s'): invalid subtype.", pysubtype); - return NULL; - } + BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items) if(size < 1 || size > PYRNA_STACK_ARRAY) { - PyErr_Format(PyExc_TypeError, "IntVectorProperty(size=%d): size must be between 0 and %d.", size, PYRNA_STACK_ARRAY); + PyErr_Format(PyExc_TypeError, "IntVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size); return NULL; } @@ -412,7 +400,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) if(srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", NULL}; - char *id=NULL, *name="", *description=""; + const char *id=NULL, *name="", *description=""; + int id_len; float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def=0.0f; int precision= 2; PropertyRNA *prop; @@ -423,24 +412,13 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) char *pyunit= NULL; int unit= PROP_UNIT_NONE; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssffffffiO!ss:FloatProperty", (char **)kwlist, &id, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssffffffiO!ss:FloatProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit)) return NULL; - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "FloatProperty(): '%s' is defined as a non-dynamic type.", id); - return NULL; - } - - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "FloatProperty(options={...}):")) - return NULL; - - if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "FloatProperty(subtype='%s'): invalid subtype.", pysubtype); - return NULL; - } + BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items) if(pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit)==0) { - PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit."); + PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit"); return NULL; } @@ -476,7 +454,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec if(srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "size", NULL}; - char *id=NULL, *name="", *description=""; + const char *id=NULL, *name="", *description=""; + int id_len; float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def[PYRNA_STACK_ARRAY]={0.0f}; int precision= 2, size=3; PropertyRNA *prop; @@ -486,24 +465,13 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec char *pysubtype= NULL; int subtype= PROP_NONE; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOfffffiO!si:FloatVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &size)) - return NULL; - - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "FloatVectorProperty(): '%s' is defined as a non-dynamic type.", id); - return NULL; - } - - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "FloatVectorProperty(options={...}):")) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|ssOfffffiO!si:FloatVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &size)) return NULL; - if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "FloatVectorProperty(subtype='%s'): invalid subtype.", pysubtype); - return NULL; - } + BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items) if(size < 1 || size > PYRNA_STACK_ARRAY) { - PyErr_Format(PyExc_TypeError, "FloatVectorProperty(size=%d): size must be between 0 and %d.", size, PYRNA_STACK_ARRAY); + PyErr_Format(PyExc_TypeError, "FloatVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size); return NULL; } @@ -543,7 +511,8 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw if(srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "maxlen", "options", "subtype", NULL}; - char *id=NULL, *name="", *description="", *def=""; + const char *id=NULL, *name="", *description="", *def=""; + int id_len; int maxlen=0; PropertyRNA *prop; PyObject *pyopts= NULL; @@ -551,21 +520,10 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw char *pysubtype= NULL; int subtype= PROP_NONE; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|sssiO!s:StringProperty", (char **)kwlist, &id, &name, &description, &def, &maxlen, &PySet_Type, &pyopts, &pysubtype)) - return NULL; - - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "StringProperty(): '%s' is defined as a non-dynamic type.", id); - return NULL; - } - - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "StringProperty(options={...}):")) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|sssiO!s:StringProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &maxlen, &PySet_Type, &pyopts, &pysubtype)) return NULL; - if(pysubtype && RNA_enum_value_from_id(property_subtype_string_items, pysubtype, &subtype)==0) { - PyErr_Format(PyExc_TypeError, "StringProperty(subtype='%s'): invalid subtype.", pysubtype); - return NULL; - } + BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items) prop= RNA_def_property(srna, id, PROP_STRING, subtype); if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */ @@ -581,49 +539,94 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw Py_RETURN_NONE; } -static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, int *defvalue) +static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) { EnumPropertyItem *items= NULL; PyObject *item; int seq_len, i, totitem= 0; + short def_used= 0; + const char *def_cmp= NULL; - if(!PySequence_Check(value)) { - PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items"); - return NULL; + seq_len= PySequence_Fast_GET_SIZE(seq_fast); + + if(is_enum_flag) { + if(seq_len > RNA_ENUM_BITFLAG_SIZE) { + PyErr_SetString(PyExc_TypeError, "EnumProperty(...): maximum " STRINGIFY(RNA_ENUM_BITFLAG_SIZE) " members for a ENUM_FLAG type property"); + return NULL; + } + if(def && !PySet_Check(def)) { + PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'set' type when ENUM_FLAG is enabled, not a '%.200s'", Py_TYPE(def)->tp_name); + return NULL; + } } + else { + if(def) { + def_cmp= _PyUnicode_AsString(def); + if(def_cmp==NULL) { + PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'str' type when ENUM_FLAG is disabled, not a '%.200s'", Py_TYPE(def)->tp_name); + return NULL; + } + } + } + + /* blank value */ + *defvalue= 0; - seq_len = PySequence_Length(value); for(i=0; i<seq_len; i++) { EnumPropertyItem tmp= {0, "", 0, "", ""}; - item= PySequence_GetItem(value, i); - if(item==NULL || PyTuple_Check(item)==0) { - PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items"); + item= PySequence_Fast_GET_ITEM(seq_fast, i); + if(PyTuple_Check(item)==0) { + PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected a sequence of tuples for the enum items"); if(items) MEM_freeN(items); - Py_XDECREF(item); return NULL; } if(!PyArg_ParseTuple(item, "sss", &tmp.identifier, &tmp.name, &tmp.description)) { - PyErr_SetString(PyExc_TypeError, "expected an identifier, name and description in the tuple"); - Py_DECREF(item); + PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected an identifier, name and description in the tuple"); return NULL; } - tmp.value= i; - RNA_enum_item_add(&items, &totitem, &tmp); + if(is_enum_flag) { + tmp.value= 1<<i; - if(def[0] && strcmp(def, tmp.identifier) == 0) - *defvalue= tmp.value; + if(def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) { + *defvalue |= tmp.value; + def_used++; + } + } + else { + tmp.value= i; - Py_DECREF(item); - } + if(def && def_used == 0 && strcmp(def_cmp, tmp.identifier)==0) { + *defvalue= tmp.value; + def_used++; /* only ever 1 */ + } + } - if(!def[0]) - *defvalue= 0; + RNA_enum_item_add(&items, &totitem, &tmp); + } RNA_enum_item_end(&items, &totitem); + if(is_enum_flag) { + /* strict check that all set members were used */ + if(def && def_used != PySet_GET_SIZE(def)) { + MEM_freeN(items); + + PyErr_Format(PyExc_TypeError, "EnumProperty(..., default={...}): set has %d unused member(s)", PySet_GET_SIZE(def) - def_used); + return NULL; + } + } + else { + if(def && def_used == 0) { + MEM_freeN(items); + + PyErr_Format(PyExc_TypeError, "EnumProperty(..., default=\'%s\'): not found in enum members", def); + return NULL; + } + } + return items; } @@ -632,9 +635,11 @@ static char BPy_EnumProperty_doc[] = "\n" " Returns a new enumerator property definition.\n" "\n" -" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n" +" :arg default: The default value for this enum, A string when *ENUM_FLAG* is disabled otherwise a set which may only contain string identifiers used in *items*.\n" +" :type default: string or set\n" +" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE', 'ENUM_FLAG'].\n" " :type options: set\n" -" :arg items: The items that make up this enumerator.\n" +" :arg items: sequence of enum items formatted: [(identifier, name, description), ...] where the identifier is used for python access and other values are used for the interface.\n" " :type items: sequence of string triplets"; static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) { @@ -644,30 +649,35 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if(srna) { static const char *kwlist[] = {"attr", "items", "name", "description", "default", "options", NULL}; - char *id=NULL, *name="", *description="", *def=""; + const char *id=NULL, *name="", *description=""; + PyObject *def= NULL; + int id_len; int defvalue=0; - PyObject *items= Py_None; + PyObject *items, *items_fast; EnumPropertyItem *eitems; PropertyRNA *prop; PyObject *pyopts= NULL; int opts=0; - if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sssO!:EnumProperty", (char **)kwlist, &id, &items, &name, &description, &def, &PySet_Type, &pyopts)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssOO!:EnumProperty", (char **)kwlist, &id, &id_len, &items, &name, &description, &def, &PySet_Type, &pyopts)) return NULL; - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "EnumProperty(): '%s' is defined as a non-dynamic type.", id); + BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items) + + if(!(items_fast= PySequence_Fast(items, "EnumProperty(...): expected a sequence of tuples for the enum items"))) { return NULL; } - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "EnumProperty(options={...}):")) - return NULL; + eitems= enum_items_from_py(items_fast, def, &defvalue, (opts & PROP_ENUM_FLAG)!=0); + + Py_DECREF(items_fast); - eitems= enum_items_from_py(items, def, &defvalue); if(!eitems) return NULL; - prop= RNA_def_enum(srna, id, eitems, defvalue, name, description); + if(opts & PROP_ENUM_FLAG) prop= RNA_def_enum_flag(srna, id, eitems, defvalue, name, description); + else prop= RNA_def_enum(srna, id, eitems, defvalue, name, description); + if(pyopts) { if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -682,13 +692,17 @@ static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix { StructRNA *srna; - srna= srna_from_self(value, "BoolProperty(...):"); + srna= srna_from_self(value, ""); if(!srna) { - - PyObject *msg= PyC_ExceptionBuffer(); - char *msg_char= _PyUnicode_AsString(msg); - PyErr_Format(PyExc_TypeError, "%.200s expected an RNA type derived from IDPropertyGroup, failed with: %s", error_prefix, msg_char); - Py_DECREF(msg); + if(PyErr_Occurred()) { + PyObject *msg= PyC_ExceptionBuffer(); + char *msg_char= _PyUnicode_AsString(msg); + PyErr_Format(PyExc_TypeError, "%.200s expected an RNA type derived from IDPropertyGroup, failed with: %s", error_prefix, msg_char); + Py_DECREF(msg); + } + else { + PyErr_Format(PyExc_TypeError, "%.200s expected an RNA type derived from IDPropertyGroup, failed with type '%s'", error_prefix, Py_TYPE(value)->tp_name); + } return NULL; } @@ -717,23 +731,18 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k if(srna) { static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL}; - char *id=NULL, *name="", *description=""; + const char *id=NULL, *name="", *description=""; + int id_len; PropertyRNA *prop; StructRNA *ptype; PyObject *type= Py_None; PyObject *pyopts= NULL; int opts=0; - if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ssO!:PointerProperty", (char **)kwlist, &id, &type, &name, &description, &PySet_Type, &pyopts)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssO!:PointerProperty", (char **)kwlist, &id, &id_len, &type, &name, &description, &PySet_Type, &pyopts)) return NULL; - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "PointerProperty(): '%s' is defined as a non-dynamic type.", id); - return NULL; - } - - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "PointerProperty(options={...}):")) - return NULL; + BPY_PROPDEF_CHECK(PointerProperty, property_flag_items) ptype= pointer_type_from_py(type, "PointerProperty(...):"); if(!ptype) @@ -766,23 +775,18 @@ static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject if(srna) { static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL}; - char *id=NULL, *name="", *description=""; + const char *id=NULL, *name="", *description=""; + int id_len; PropertyRNA *prop; StructRNA *ptype; PyObject *type= Py_None; PyObject *pyopts= NULL; int opts=0; - if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ssO!:CollectionProperty", (char **)kwlist, &id, &type, &name, &description, &PySet_Type, &pyopts)) - return NULL; - - if(RNA_def_property_free_identifier(srna, id) == -1) { - PyErr_Format(PyExc_TypeError, "CollectionProperty(): '%s' is defined as a non-dynamic type.", id); + if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssO!:CollectionProperty", (char **)kwlist, &id, &id_len, &type, &name, &description, &PySet_Type, &pyopts)) return NULL; - } - if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "CollectionProperty(options={...}):")) - return NULL; + BPY_PROPDEF_CHECK(CollectionProperty, property_flag_items) ptype= pointer_type_from_py(type, "CollectionProperty(...):"); if(!ptype) @@ -827,7 +831,7 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw return NULL; /* self's type was compatible but error getting the srna */ } else if(srna==NULL) { - PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type."); + PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type"); return NULL; } else { @@ -839,7 +843,7 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw return NULL; if(RNA_def_property_free_identifier(srna, id) != 1) { - PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property.", id); + PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id); return NULL; } } |