diff options
Diffstat (limited to 'source/blender/python/intern/bpy_rna.c')
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 214 |
1 files changed, 136 insertions, 78 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index cbc75d35bce..cd1f7dbc102 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1154,19 +1154,43 @@ static PySequenceMethods pyrna_prop_as_sequence = { static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA * self, PyObject *args) { - char *path; + char *path, *path_full; int index= 0; float cfra = CTX_data_scene(BPy_GetContext())->r.cfra; + PropertyRNA *prop; + PyObject *result; + + if (!PyArg_ParseTuple(args, "s|if:keyframe_insert", &path, &index, &cfra)) + return NULL; - if(!RNA_struct_is_ID(self->ptr.type)) { - PyErr_SetString( PyExc_TypeError, "StructRNA - keyframe_insert only for ID type"); + 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); + + if (path_full==NULL) { + PyErr_Format( PyExc_TypeError, "keyframe_insert, could not make path to \"%s\"", path); return NULL; + } - return PyBool_FromLong( insert_keyframe((ID *)self->ptr.data, NULL, NULL, path, index, cfra, 0)); + 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_is_property_set(BPy_StructRNA * self, PyObject *args) @@ -1366,10 +1390,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; } @@ -2382,7 +2410,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 */ @@ -2698,6 +2726,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 @@ -2714,26 +2743,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; } @@ -2787,13 +2816,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. @@ -2805,6 +2831,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; @@ -2817,13 +2847,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. @@ -2835,6 +2862,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; @@ -2847,13 +2878,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. @@ -2865,6 +2893,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; @@ -2877,13 +2909,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. @@ -2895,6 +2924,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; @@ -2953,15 +2986,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. @@ -2973,6 +3003,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; @@ -3009,13 +3043,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. @@ -3027,6 +3058,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; @@ -3044,13 +3079,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. @@ -3062,6 +3094,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; @@ -3076,50 +3112,58 @@ 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; + PyObject *dummy_args, *item, *key; + Py_ssize_t pos = 0; - props= PyObject_GetAttrString(py_class, "__props__"); + dummy_args = PyTuple_New(0); - if(!props) { - PyErr_Clear(); - return 1; - } + while (PyDict_Next(class_dict, &pos, &key, &item)) { + PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret; + /* 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)) { - dummy_args = PyTuple_New(0); + PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *); + pyfunc = PyCObject_AsVoidPtr(py_func_ptr); + py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL); - for(i=0; i<PyList_Size(props); i++) { - PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret; - item = PyList_GET_ITEM(props, i); - - 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); - - py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw); - Py_DECREF(py_srna_cobject); + /* 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); + + if(py_ret) { + Py_DECREF(py_ret); + } + else { + PyErr_Print(); + PyErr_Clear(); - if(py_ret) { - Py_DECREF(py_ret); + 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 -1; + } } else { - Py_DECREF(dummy_args); - return 0; + /* 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(); + } } - else { - 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 ------------------------*/ @@ -3153,7 +3197,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)) { @@ -3224,11 +3268,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) { @@ -3239,7 +3285,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; } @@ -3482,8 +3529,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)) - return NULL; + /* 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; } |