diff options
Diffstat (limited to 'source/blender/python/intern/bpy_rna.c')
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 331 |
1 files changed, 255 insertions, 76 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index a60de529e8f..c29eafc8b74 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -41,6 +41,7 @@ /* only for keyframing */ #include "DNA_scene_types.h" +#include "DNA_anim_types.h" #include "ED_keyframing.h" #define USE_MATHUTILS @@ -71,6 +72,7 @@ static int mathutils_rna_vector_set(BPy_PropertyRNA *self, int subtype, float *v return 0; RNA_property_float_set_array(&self->ptr, self->prop, vec_to); + RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); return 1; } @@ -89,6 +91,7 @@ static int mathutils_rna_vector_set_index(BPy_PropertyRNA *self, int subtype, fl return 0; RNA_property_float_set_index(&self->ptr, self->prop, index, vec_to[index]); + RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); return 1; } @@ -119,6 +122,7 @@ static int mathutils_rna_matrix_set(BPy_PropertyRNA *self, int subtype, float *m return 0; RNA_property_float_set_array(&self->ptr, self->prop, mat_to); + RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); return 1; } @@ -1124,11 +1128,24 @@ static int pyrna_prop_contains(BPy_PropertyRNA * self, PyObject *value) return 0; } +static PyObject *pyrna_prop_item(BPy_PropertyRNA * self, Py_ssize_t index) +{ + /* reuse subscript functions */ + if (RNA_property_type(self->prop) == PROP_COLLECTION) { + return prop_subscript_collection_int(self, index); + } else if (RNA_property_array_check(&self->ptr, self->prop)) { + return prop_subscript_array_int(self, index); + } + + PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection"); + return NULL; +} + static PySequenceMethods pyrna_prop_as_sequence = { NULL, /* Cant set the len otherwise it can evaluate as false */ NULL, /* sq_concat */ NULL, /* sq_repeat */ - NULL, /* sq_item */ + (ssizeargfunc)pyrna_prop_item, /* sq_item */ /* Only set this so PySequence_Check() returns True */ NULL, /* sq_slice */ NULL, /* sq_ass_item */ NULL, /* sq_ass_slice */ @@ -1138,21 +1155,87 @@ static PySequenceMethods pyrna_prop_as_sequence = { static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA * self, PyObject *args) { - char *path; - int index= 0; + char *path, *path_full; + int index= -1; /* default to all */ float cfra = CTX_data_scene(BPy_GetContext())->r.cfra; + PropertyRNA *prop; + PyObject *result; - if(!RNA_struct_is_ID(self->ptr.type)) { - PyErr_SetString( PyExc_TypeError, "StructRNA - keyframe_insert only for ID type"); + if (!PyArg_ParseTuple(args, "s|if:keyframe_insert", &path, &index, &cfra)) + return NULL; + + if (self->ptr.data==NULL) { + PyErr_Format( PyExc_TypeError, "keyframe_insert, this struct has no data, cant be animated", path); return NULL; } - if (!PyArg_ParseTuple(args, "s|if:keyframe_insert", &path, &index, &cfra)) + prop = RNA_struct_find_property(&self->ptr, path); + + if (prop==NULL) { + PyErr_Format( PyExc_TypeError, "keyframe_insert, property \"%s\" not found", path); return NULL; + } + + if (!RNA_property_animateable(&self->ptr, prop)) { + PyErr_Format( PyExc_TypeError, "keyframe_insert, property \"%s\" not animatable", path); + return NULL; + } + + path_full= RNA_path_from_ID_to_property(&self->ptr, prop); - return PyBool_FromLong( insert_keyframe((ID *)self->ptr.data, NULL, NULL, path, index, cfra, 0)); + if (path_full==NULL) { + PyErr_Format( PyExc_TypeError, "keyframe_insert, could not make path to \"%s\"", path); + return NULL; + } + + result= PyBool_FromLong( insert_keyframe((ID *)self->ptr.id.data, NULL, NULL, path_full, index, cfra, 0)); + MEM_freeN(path_full); + + return result; } + +static PyObject *pyrna_struct_driver_add(BPy_StructRNA * self, PyObject *args) +{ + char *path, *path_full; + int index= -1; /* default to all */ + PropertyRNA *prop; + PyObject *result; + + if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index)) + return NULL; + + if (self->ptr.data==NULL) { + PyErr_Format( PyExc_TypeError, "driver_add, this struct has no data, cant be animated", path); + return NULL; + } + + prop = RNA_struct_find_property(&self->ptr, path); + + if (prop==NULL) { + PyErr_Format( PyExc_TypeError, "driver_add, property \"%s\" not found", path); + return NULL; + } + + if (!RNA_property_animateable(&self->ptr, prop)) { + PyErr_Format( PyExc_TypeError, "driver_add, property \"%s\" not animatable", path); + return NULL; + } + + path_full= RNA_path_from_ID_to_property(&self->ptr, prop); + + if (path_full==NULL) { + PyErr_Format( PyExc_TypeError, "driver_add, could not make path to \"%s\"", path); + return NULL; + } + + result= PyBool_FromLong( ANIM_add_driver((ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON)); + MEM_freeN(path_full); + + return result; +} + + static PyObject *pyrna_struct_is_property_set(BPy_StructRNA * self, PyObject *args) { char *name; @@ -1178,7 +1261,6 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA * self, PyObject return PyBool_FromLong(hidden); } - static PyObject *pyrna_struct_dir(BPy_StructRNA * self) { PyObject *ret, *dict; @@ -1263,6 +1345,13 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self) BLI_freelistN(&lb); } + /* Hard coded names */ + { + pystring = PyUnicode_FromString("id_data"); + PyList_Append(ret, pystring); + Py_DECREF(pystring); + } + return ret; } @@ -1319,6 +1408,16 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) BLI_freelistN(&newlb); } + else if (strcmp(name, "id_data")==0) { /* XXX - hard coded */ + if(self->ptr.id.data) { + PointerRNA id_ptr; + RNA_id_pointer_create((ID *)self->ptr.id.data, &id_ptr); + return pyrna_struct_CreatePyObject(&id_ptr); + } + else { + Py_RETURN_NONE; + } + } else { PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name); ret = NULL; @@ -1334,10 +1433,14 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje PropertyRNA *prop = RNA_struct_find_property(&self->ptr, name); if (prop==NULL) { + // XXX - This currently allows anything to be assigned to an rna prop, need to see how this should be used + // but for now it makes porting scripts confusing since it fails silently. +#if 0 if (!BPy_StructRNA_CheckExact(self) && PyObject_GenericSetAttr((PyObject *)self, pyname, value) >= 0) { return 0; - } - else { + } else +#endif + { PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name); return -1; } @@ -1352,6 +1455,54 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "StructRNA - Attribute (setattr):"); } +static PyObject *pyrna_prop_getattro( BPy_PropertyRNA * self, PyObject *pyname ) +{ + char *name = _PyUnicode_AsString(pyname); + + if(strcmp(name, "active")==0) { + PropertyRNA *prop_act; + + if (RNA_property_type(self->prop) != PROP_COLLECTION) { + PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not a collection"); + return NULL; + } + + prop_act= RNA_property_collection_active(self->prop); + if (prop_act==NULL) { + PyErr_SetString( PyExc_TypeError, "collection has no active"); + return NULL; + } + + return pyrna_prop_to_py(&self->ptr, prop_act); + } + + return PyObject_GenericGetAttr((PyObject *)self, pyname); +} + +//--------------- setattr------------------------------------------- +static int pyrna_prop_setattro( BPy_PropertyRNA * self, PyObject *pyname, PyObject * value ) +{ + char *name = _PyUnicode_AsString(pyname); + if(strcmp(name, "active")==0) { + PropertyRNA *prop_act; + + if (RNA_property_type(self->prop) != PROP_COLLECTION) { + PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not a collection"); + return -1; + } + + prop_act= RNA_property_collection_active(self->prop); + if (prop_act==NULL) { + PyErr_SetString( PyExc_TypeError, "collection has no active"); + return -1; + } + + return pyrna_py_to_prop(&self->ptr, prop_act, NULL, value, "StructRNA - Attribute (setattr):"); + } + + return PyObject_GenericSetAttr((PyObject *)self, pyname, value); +} + static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) { PyObject *ret; @@ -1770,6 +1921,7 @@ static struct PyMethodDef pyrna_struct_methods[] = { /* maybe this become and ID function */ {"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, NULL}, + {"driver_add", (PyCFunction)pyrna_struct_driver_add, METH_VARARGS, NULL}, {"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, NULL}, {"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, NULL}, @@ -1790,7 +1942,6 @@ static struct PyMethodDef pyrna_prop_methods[] = { /* array accessor function */ {"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL}, {"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL}, - {NULL, NULL, 0, NULL} }; @@ -2261,8 +2412,10 @@ PyTypeObject pyrna_prop_Type = { NULL, /* hashfunc tp_hash; */ NULL, /* ternaryfunc tp_call; */ NULL, /* reprfunc tp_str; */ - NULL, /*PyObject_GenericGetAttr - MINGW Complains, assign later */ /* getattrofunc tp_getattro; */ /* will only use these if this is a subtype of a py class */ - NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */ /* setattrofunc tp_setattro; */ + + /* will only use these if this is a subtype of a py class */ + ( getattrofunc ) pyrna_prop_getattro, /* getattrofunc tp_getattro; */ + ( setattrofunc ) pyrna_prop_setattro, /* setattrofunc tp_setattro; */ /* Functions to access object as input/output buffer */ NULL, /* PyBufferProcs *tp_as_buffer; */ @@ -2350,7 +2503,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) item = pyrna_struct_CreatePyObject(&ptr); //item = PyCObject_FromVoidPtr(srna, NULL); - PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", item); + PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "bl_rna", item); Py_DECREF(item); /* done with rna instance */ @@ -2529,10 +2682,6 @@ PyObject *BPY_rna_module( void ) mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb); #endif - /* This can't be set in the pytype struct because some compilers complain */ - pyrna_prop_Type.tp_getattro = PyObject_GenericGetAttr; - pyrna_prop_Type.tp_setattro = PyObject_GenericSetAttr; - if( PyType_Ready( &pyrna_struct_Type ) < 0 ) return NULL; @@ -2666,6 +2815,7 @@ PyObject *BPY_rna_props( void ) { PyObject *submodule; submodule= PyModule_Create(&props_module); + PyDict_SetItemString(PySys_GetObject("modules"), props_module.m_name, submodule); /* INCREF since its its assumed that all these functions return the * module with a new ref like PyDict_New, since they are passed to @@ -2682,26 +2832,26 @@ static StructRNA *pyrna_struct_as_srna(PyObject *self) /* ack, PyObject_GetAttrString wont look up this types tp_dict first :/ */ if(PyType_Check(self)) { - py_srna = (BPy_StructRNA *)PyDict_GetItemString(((PyTypeObject *)self)->tp_dict, "__rna__"); + py_srna = (BPy_StructRNA *)PyDict_GetItemString(((PyTypeObject *)self)->tp_dict, "bl_rna"); Py_XINCREF(py_srna); } if(py_srna==NULL) - py_srna = (BPy_StructRNA*)PyObject_GetAttrString(self, "__rna__"); + py_srna = (BPy_StructRNA*)PyObject_GetAttrString(self, "bl_rna"); if(py_srna==NULL) { - PyErr_SetString(PyExc_SystemError, "internal error, self had no __rna__ attribute, should never happen."); + PyErr_SetString(PyExc_SystemError, "internal error, self had no bl_rna attribute, should never happen."); return NULL; } if(!BPy_StructRNA_Check(py_srna)) { - PyErr_Format(PyExc_SystemError, "internal error, __rna__ was of type %.200s, instead of %.200s instance.", Py_TYPE(py_srna)->tp_name, pyrna_struct_Type.tp_name); + PyErr_Format(PyExc_SystemError, "internal error, bl_rna was of type %.200s, instead of %.200s instance.", Py_TYPE(py_srna)->tp_name, pyrna_struct_Type.tp_name); Py_DECREF(py_srna); return NULL; } if(py_srna->ptr.type != &RNA_Struct) { - PyErr_SetString(PyExc_SystemError, "internal error, __rna__ was not a RNA_Struct type of rna struct."); + PyErr_SetString(PyExc_SystemError, "internal error, bl_rna was not a RNA_Struct type of rna struct."); Py_DECREF(py_srna); return NULL; } @@ -2755,13 +2905,10 @@ static PyObject *bpy_prop_deferred_return(void *func, PyObject *kw) PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = {"attr", "name", "description", "default", NULL}; - char *id, *name="", *description=""; + char *id=NULL, *name="", *description=""; int def=0; PropertyRNA *prop; StructRNA *srna; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def)) - return NULL; if (PyTuple_Size(args) > 0) { PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. @@ -2773,6 +2920,10 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; /* self's type was compatible but error getting the srna */ } else if(srna) { + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def)) + return NULL; + prop= RNA_def_boolean(srna, id, def, name, description); RNA_def_property_duplicate_pointers(prop); Py_RETURN_NONE; @@ -2785,13 +2936,10 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; - char *id, *name="", *description=""; + char *id=NULL, *name="", *description=""; int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, def=0; PropertyRNA *prop; StructRNA *srna; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def)) - return NULL; if (PyTuple_Size(args) > 0) { PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. @@ -2803,6 +2951,10 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; /* self's type was compatible but error getting the srna */ } else if(srna) { + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def)) + return NULL; + prop= RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max); RNA_def_property_duplicate_pointers(prop); Py_RETURN_NONE; @@ -2815,13 +2967,10 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; - char *id, *name="", *description=""; + char *id=NULL, *name="", *description=""; float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, def=0.0f; PropertyRNA *prop; StructRNA *srna; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def)) - return NULL; if (PyTuple_Size(args) > 0) { PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. @@ -2833,6 +2982,10 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; /* self's type was compatible but error getting the srna */ } else if(srna) { + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def)) + return NULL; + prop= RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max); RNA_def_property_duplicate_pointers(prop); Py_RETURN_NONE; @@ -2845,13 +2998,10 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = {"attr", "name", "description", "maxlen", "default", NULL}; - char *id, *name="", *description="", *def=""; + char *id=NULL, *name="", *description="", *def=""; int maxlen=0; PropertyRNA *prop; StructRNA *srna; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssis:StringProperty", kwlist, &id, &name, &description, &maxlen, &def)) - return NULL; if (PyTuple_Size(args) > 0) { PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. @@ -2863,6 +3013,10 @@ PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; /* self's type was compatible but error getting the srna */ } else if(srna) { + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssis:StringProperty", kwlist, &id, &name, &description, &maxlen, &def)) + return NULL; + prop= RNA_def_string(srna, id, def, maxlen, name, description); RNA_def_property_duplicate_pointers(prop); Py_RETURN_NONE; @@ -2921,15 +3075,12 @@ static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, in PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = {"attr", "items", "name", "description", "default", NULL}; - char *id, *name="", *description="", *def=""; + char *id=NULL, *name="", *description="", *def=""; int defvalue=0; PyObject *items= Py_None; EnumPropertyItem *eitems; PropertyRNA *prop; StructRNA *srna; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sss:EnumProperty", kwlist, &id, &items, &name, &description, &def)) - return NULL; if (PyTuple_Size(args) > 0) { PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. @@ -2941,6 +3092,10 @@ PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; /* self's type was compatible but error getting the srna */ } else if(srna) { + + if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sss:EnumProperty", kwlist, &id, &items, &name, &description, &def)) + return NULL; + eitems= enum_items_from_py(items, def, &defvalue); if(!eitems) return NULL; @@ -2977,13 +3132,10 @@ static StructRNA *pointer_type_from_py(PyObject *value) PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = {"attr", "type", "name", "description", NULL}; - char *id, *name="", *description=""; + char *id=NULL, *name="", *description=""; PropertyRNA *prop; StructRNA *srna, *ptype; PyObject *type= Py_None; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:PointerProperty", kwlist, &id, &type, &name, &description)) - return NULL; if (PyTuple_Size(args) > 0) { PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. @@ -2995,6 +3147,10 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; /* self's type was compatible but error getting the srna */ } else if(srna) { + + if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:PointerProperty", kwlist, &id, &type, &name, &description)) + return NULL; + ptype= pointer_type_from_py(type); if(!ptype) return NULL; @@ -3012,13 +3168,10 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = {"attr", "type", "name", "description", NULL}; - char *id, *name="", *description=""; + char *id=NULL, *name="", *description=""; PropertyRNA *prop; StructRNA *srna, *ptype; PyObject *type= Py_None; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:CollectionProperty", kwlist, &id, &type, &name, &description)) - return NULL; if (PyTuple_Size(args) > 0) { PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. @@ -3030,6 +3183,10 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; /* self's type was compatible but error getting the srna */ } else if(srna) { + + if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ss:CollectionProperty", kwlist, &id, &type, &name, &description)) + return NULL; + ptype= pointer_type_from_py(type); if(!ptype) return NULL; @@ -3044,29 +3201,27 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; } -static int deferred_register_props(PyObject *py_class, StructRNA *srna) +int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) { - PyObject *props, *dummy_args, *item; - int i; - - props= PyObject_GetAttrString(py_class, "__props__"); - - if(!props) { - PyErr_Clear(); - return 1; - } + PyObject *dummy_args, *item, *key; + Py_ssize_t pos = 0; dummy_args = PyTuple_New(0); - - for(i=0; i<PyList_Size(props); i++) { + + while (PyDict_Next(class_dict, &pos, &key, &item)) { PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret; - item = PyList_GET_ITEM(props, i); - + /* We only care about results from C which + * are for sure types, save some time with error */ + if(PyTuple_CheckExact(item)) { if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) { + PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *); pyfunc = PyCObject_AsVoidPtr(py_func_ptr); py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL); - + + /* not 100% nice :/, modifies the dict passed, should be ok */ + PyDict_SetItemString(py_kw, "attr", key); + py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw); Py_DECREF(py_srna_cobject); @@ -3074,20 +3229,30 @@ static int deferred_register_props(PyObject *py_class, StructRNA *srna) Py_DECREF(py_ret); } else { + PyErr_Print(); + PyErr_Clear(); + + PyLineSpit(); + + PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not run\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); Py_DECREF(dummy_args); - return 0; + return -1; } } else { + /* Since this is a class dict, ignore args that can't be passed */ + + /* for testing only */ + /* PyObSpit("Why doesn't this work??", item); + PyErr_Print(); */ PyErr_Clear(); - PyErr_SetString(PyExc_AttributeError, "expected list of dicts for __props__."); - Py_DECREF(dummy_args); - return 0; + } } + } Py_DECREF(dummy_args); - return 1; + return 0; } /*-------------------- Type Registration ------------------------*/ @@ -3121,7 +3286,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun PyObject *item, *fitem; PyObject *py_arg_count; int i, flag, arg_count, func_arg_count; - char identifier[128]; + const char *identifier; if (base_class) { if (!PyObject_IsSubclass(py_class, base_class)) { @@ -3192,11 +3357,13 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun if(!(flag & PROP_REGISTER)) continue; - BLI_snprintf(identifier, sizeof(identifier), "__%s__", RNA_property_identifier(prop)); + identifier= RNA_property_identifier(prop); item = PyObject_GetAttrString(py_class, identifier); if (item==NULL) { - if(strcmp(identifier, "__idname__") == 0) { + + /* Sneaky workaround to use the class name as the bl_idname */ + if(strcmp(identifier, "bl_idname") == 0) { item= PyObject_GetAttrString(py_class, "__name__"); if(item) { @@ -3207,7 +3374,8 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun } } - if (item==NULL && (flag & PROP_REGISTER_OPTIONAL)==0) { + + if (item == NULL && (((flag & PROP_REGISTER_OPTIONAL) != PROP_REGISTER_OPTIONAL))) { PyErr_Format( PyExc_AttributeError, "expected %.200s class to have an \"%.200s\" attribute", class_type, identifier); return -1; } @@ -3450,8 +3618,19 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class) // Py_DECREF(py_class); // shuld be able to do this XXX since the old rna adds a new ref. } - if(!deferred_register_props(py_class, srna_new)) + /* Can't use this because it returns a dict proxy + * + * item= PyObject_GetAttrString(py_class, "__dict__"); + */ + item= ((PyTypeObject*)py_class)->tp_dict; + if(item) { + if(pyrna_deferred_register_props(srna_new, item)!=0) { return NULL; + } + } + else { + PyErr_Clear(); + } Py_RETURN_NONE; } |