=IDProperties bugfix=

Another bug from the tracker, reported by Mike Stramba.
A duplicated Py_XDECREF in the wrong place made assigning
arrays from Vector objects not work.

Also, fixed nasty bug in C API of idproperties (the function
to look up a property from a group was broken).  Fixed a memory
leak too.

In addition, made "del group['property']" delete properties
from group; previously this would just crash (or at least it
should have).  Added a small addition to the example in the
epydocs for IDGroup.
This commit is contained in:
Joseph Eagar 2006-12-01 03:04:36 +00:00
parent b36b940807
commit 71da111613
4 changed files with 31 additions and 5 deletions

@ -94,7 +94,17 @@ struct. In the future this will just be IDP_FreeProperty and the code will
be reorganized to work properly. be reorganized to work properly.
*/ */
int IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop); int IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop);
/*NOTE: this does not free the property!!
To free the property, you have to do:
IDP_FreeProperty(prop); //free all subdata
MEM_freeN(prop); //free property struct itself
*/
void IDP_RemFromGroup(struct IDProperty *group, struct IDProperty *prop); void IDP_RemFromGroup(struct IDProperty *group, struct IDProperty *prop);
IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, char *name); IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, char *name);
/*Get an iterator to iterate over the members of an id property group. /*Get an iterator to iterate over the members of an id property group.

@ -192,7 +192,7 @@ IDProperty *IDP_GetPropertyFromGroup(IDProperty *prop, char *name)
{ {
IDProperty *loop; IDProperty *loop;
for (loop=prop->data.group.first; loop; loop=loop->next) { for (loop=prop->data.group.first; loop; loop=loop->next) {
if (strcmp(prop->name, name)==0) return prop; if (strcmp(loop->name, name)==0) return loop;
} }
return NULL; return NULL;
} }

@ -249,7 +249,6 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
prop = IDP_New(IDP_ARRAY, val, name); prop = IDP_New(IDP_ARRAY, val, name);
for (i=0; i<val.array.len; i++) { for (i=0; i<val.array.len; i++) {
item = PySequence_GetItem(ob, i); item = PySequence_GetItem(ob, i);
Py_XDECREF(item);
if (val.array.type == IDP_INT) { if (val.array.type == IDP_INT) {
item = PyNumber_Int(item); item = PyNumber_Int(item);
((int*)prop->data.pointer)[i] = (int)PyInt_AsLong(item); ((int*)prop->data.pointer)[i] = (int)PyInt_AsLong(item);
@ -292,10 +291,13 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
} }
Py_XDECREF(keys); Py_XDECREF(keys);
Py_XDECREF(vals); Py_XDECREF(vals);
} } else return "invalid property value";
if (IDP_GetPropertyFromGroup(group, prop->name) == NULL) { if (IDP_GetPropertyFromGroup(group, prop->name) != NULL) {
IDP_RemFromGroup(group, IDP_GetPropertyFromGroup(group, prop->name)); IDProperty *prop2 = IDP_GetPropertyFromGroup(group, prop->name);
IDP_RemFromGroup(group, prop2);
IDP_FreeProperty(prop2);
MEM_freeN(prop2);
} }
IDP_AddToGroup(group, prop); IDP_AddToGroup(group, prop);
@ -314,6 +316,16 @@ int BPy_IDProperty_Map_SetItem(BPy_IDProperty *self, PyObject *key, PyObject *va
return EXPP_ReturnIntError( PyExc_TypeError, return EXPP_ReturnIntError( PyExc_TypeError,
"only strings are allowed as subgroup keys" ); "only strings are allowed as subgroup keys" );
if (val == NULL) {
IDProperty *pkey = IDP_GetPropertyFromGroup(self->prop, PyString_AsString(key));
if (pkey) {
IDP_RemFromGroup(self->prop, pkey);
IDP_FreeProperty(pkey);
MEM_freeN(pkey);
return 0;
} else return EXPP_ReturnIntError( PyExc_RuntimeError, "property not found in group" );
}
err = BPy_IDProperty_Map_ValidateAndCreate(PyString_AsString(key), self->prop, val); err = BPy_IDProperty_Map_ValidateAndCreate(PyString_AsString(key), self->prop, val);
if (err) return EXPP_ReturnIntError( PyExc_RuntimeError, err ); if (err) return EXPP_ReturnIntError( PyExc_RuntimeError, err );

@ -37,6 +37,10 @@ class IDGroup:
Note that for arrays, the array type defaults to int unless a float is found Note that for arrays, the array type defaults to int unless a float is found
while scanning the template list; if any floats are found, then the whole while scanning the template list; if any floats are found, then the whole
array is float. array is float.
You can also delete properties with the del operator. For example:
del group['property']
""" """
def newProperty(type, name, array_type="Float", val=""): def newProperty(type, name, array_type="Float", val=""):