diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-01-25 09:54:57 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-01-25 09:54:57 +0300 |
commit | c0e74f9dce632795ed6e083436353b4df4d7e62c (patch) | |
tree | cc5d6f06da0bdb5d4f73a4c040bfcc9159b74a31 /source/blender | |
parent | 17509e733429bdcc3a6131a775d2d73252b6bb88 (diff) |
fix [#25748] Addons register parameters/functions more than once
- values were added to both the classes __dict__ as well as the internal StructRNA.
- made properties available from the type since this is where the python api assigns them:
>>> bpy.types.Scene.frame_start
<bpy_struct, IntProperty("frame_start")>
- rename RNA_struct_type_properties() -> RNA_struct_type_properties(), added RNA_struct_type_find_property()
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 8 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 59 |
4 files changed, 54 insertions, 20 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index a6f03c0c3ec..85c82dbf9bc 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3119,7 +3119,7 @@ static int node_animation_properties(bNodeTree *ntree, bNode *node) /* check to see if any of the node's properties have fcurves */ RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr); - lb = RNA_struct_defined_properties(ptr.type); + lb = RNA_struct_type_properties(ptr.type); for (link=lb->first; link; link=link->next) { int driven, len=1, index; diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 4d9e6a92bea..56b7cdc6c95 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -617,7 +617,10 @@ int RNA_struct_idprops_register_check(StructRNA *type); PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier); -const struct ListBase *RNA_struct_defined_properties(StructRNA *srna); + +/* lower level functions for access to type properties */ +const struct ListBase *RNA_struct_type_properties(StructRNA *srna); +PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier); FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier); const struct ListBase *RNA_struct_defined_functions(StructRNA *srna); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index cc2e5fc909f..15a26711d1c 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -569,11 +569,17 @@ PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna) return prop; } -const struct ListBase *RNA_struct_defined_properties(StructRNA *srna) +/* low level direct access to type->properties, note this ignores parent classes so should be used with care */ +const struct ListBase *RNA_struct_type_properties(StructRNA *srna) { return &srna->cont.properties; } +PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier) +{ + return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier)); +} + FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier) { #if 1 diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index fc36784ef84..b57683742fc 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2831,14 +2831,29 @@ static int pyrna_is_deferred_prop(PyObject *value) return PyTuple_CheckExact(value) && PyTuple_GET_SIZE(value)==2 && PyCallable_Check(PyTuple_GET_ITEM(value, 0)) && PyDict_CheckExact(PyTuple_GET_ITEM(value, 1)); } -static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *pyname) -{ - return PyType_Type.tp_getattro(cls, pyname); +static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr) +{ + PyObject *ret= PyType_Type.tp_getattro(cls, attr); + + if(ret == NULL) { + StructRNA *srna= srna_from_self(cls, "StructRNA.__getattr__"); + if(srna) { + PropertyRNA *prop= RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr)); + if(prop) { + PointerRNA tptr; + PyErr_Clear(); /* clear error from tp_getattro */ + RNA_pointer_create(NULL, &RNA_Property, prop, &tptr); + ret= pyrna_struct_CreatePyObject(&tptr); + } + } + } + + return ret; } static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyObject *value) { - StructRNA *srna= srna_from_self(cls, ""); + StructRNA *srna= srna_from_self(cls, "StructRNA.__setattr__"); if(srna == NULL) { if(value && pyrna_is_deferred_prop(value)) { @@ -2854,10 +2869,8 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb if(value) { /* check if the value is a property */ if(pyrna_is_deferred_prop(value)) { - int ret= deferred_register_prop(srna, attr, value); - if(ret < 0) - return ret; - /* pass through, when the value isn't assigned it still works but gets confusing from script writers POV */ + /* dont add this to the __dict__, getattr deals with returning the newly created RNA_Property type */ + return deferred_register_prop(srna, attr, value); } else { /* remove existing property if its set or we also end up with confusement */ @@ -2874,7 +2887,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb return -1; } } - + /* fallback to standard py, delattr/setattr */ return PyType_Type.tp_setattro(cls, attr, value); } @@ -4951,12 +4964,10 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_pr /* Orphan functions, not sure where they should go */ /* get the srna for methods attached to types */ -/* */ +/* + * Caller needs to raise error.*/ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) { - /* a bit sloppy but would cause a very confusing bug if - * an error happened to be set here */ - PyErr_Clear(); if(self==NULL) { return NULL; @@ -4967,10 +4978,24 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) else if (PyType_Check(self)==0) { return NULL; } - /* These cases above not errors, they just mean the type was not compatible - * After this any errors will be raised in the script */ + else { + /* These cases above not errors, they just mean the type was not compatible + * After this any errors will be raised in the script */ + + PyObject *error_type, *error_value, *error_traceback; + StructRNA *srna; + + PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyErr_Clear(); - return pyrna_struct_as_srna(self, 0, error_prefix); + srna= pyrna_struct_as_srna(self, 0, error_prefix); + + if(!PyErr_Occurred()) { + PyErr_Restore(error_type, error_value, error_traceback); + } + + return srna; + } } static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item) @@ -5200,7 +5225,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun } /* verify properties */ - lb= RNA_struct_defined_properties(srna); + lb= RNA_struct_type_properties(srna); for(link=lb->first; link; link=link->next) { const char *identifier; prop= (PropertyRNA*)link; |