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()
This commit is contained in:
@@ -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 */
|
/* check to see if any of the node's properties have fcurves */
|
||||||
RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
|
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) {
|
for (link=lb->first; link; link=link->next) {
|
||||||
int driven, len=1, index;
|
int driven, len=1, index;
|
||||||
|
|||||||
@@ -617,7 +617,10 @@ int RNA_struct_idprops_register_check(StructRNA *type);
|
|||||||
|
|
||||||
|
|
||||||
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier);
|
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);
|
FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier);
|
||||||
const struct ListBase *RNA_struct_defined_functions(StructRNA *srna);
|
const struct ListBase *RNA_struct_defined_functions(StructRNA *srna);
|
||||||
|
|||||||
@@ -569,11 +569,17 @@ PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
|
|||||||
return prop;
|
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;
|
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)
|
FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
|
|||||||
@@ -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));
|
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)
|
static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr)
|
||||||
{
|
{
|
||||||
return PyType_Type.tp_getattro(cls, pyname);
|
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)
|
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(srna == NULL) {
|
||||||
if(value && pyrna_is_deferred_prop(value)) {
|
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) {
|
if(value) {
|
||||||
/* check if the value is a property */
|
/* check if the value is a property */
|
||||||
if(pyrna_is_deferred_prop(value)) {
|
if(pyrna_is_deferred_prop(value)) {
|
||||||
int ret= deferred_register_prop(srna, attr, value);
|
/* dont add this to the __dict__, getattr deals with returning the newly created RNA_Property type */
|
||||||
if(ret < 0)
|
return deferred_register_prop(srna, attr, value);
|
||||||
return ret;
|
|
||||||
/* pass through, when the value isn't assigned it still works but gets confusing from script writers POV */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* remove existing property if its set or we also end up with confusement */
|
/* 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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fallback to standard py, delattr/setattr */
|
/* fallback to standard py, delattr/setattr */
|
||||||
return PyType_Type.tp_setattro(cls, attr, value);
|
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 */
|
/* Orphan functions, not sure where they should go */
|
||||||
/* get the srna for methods attached to types */
|
/* get the srna for methods attached to types */
|
||||||
/* */
|
/*
|
||||||
|
* Caller needs to raise error.*/
|
||||||
StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
|
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) {
|
if(self==NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -4967,10 +4978,24 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
|
|||||||
else if (PyType_Check(self)==0) {
|
else if (PyType_Check(self)==0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* These cases above not errors, they just mean the type was not compatible
|
else {
|
||||||
* After this any errors will be raised in the script */
|
/* These cases above not errors, they just mean the type was not compatible
|
||||||
|
* After this any errors will be raised in the script */
|
||||||
|
|
||||||
return pyrna_struct_as_srna(self, 0, error_prefix);
|
PyObject *error_type, *error_value, *error_traceback;
|
||||||
|
StructRNA *srna;
|
||||||
|
|
||||||
|
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||||
|
PyErr_Clear();
|
||||||
|
|
||||||
|
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)
|
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 */
|
/* verify properties */
|
||||||
lb= RNA_struct_defined_properties(srna);
|
lb= RNA_struct_type_properties(srna);
|
||||||
for(link=lb->first; link; link=link->next) {
|
for(link=lb->first; link; link=link->next) {
|
||||||
const char *identifier;
|
const char *identifier;
|
||||||
prop= (PropertyRNA*)link;
|
prop= (PropertyRNA*)link;
|
||||||
|
|||||||
Reference in New Issue
Block a user