bpy/rna methods to find properties (works nice with autocomp!)
authorCampbell Barton <ideasman42@gmail.com>
Mon, 16 Nov 2009 20:16:45 +0000 (20:16 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 16 Nov 2009 20:16:45 +0000 (20:16 +0000)
keys(), values() & items()

ed...
 print(bpy.context.active_object.keys())

Possible name conflict here, need to keep an eye on it.

source/blender/python/generic/IDProp.c
source/blender/python/generic/IDProp.h
source/blender/python/intern/bpy_rna.c

index 3ec3f30bb0f3bb3d6c9088e5be2889f39042b242..ccb6814993142ce3c8eac7db67b78ace17a6b3b3 100644 (file)
@@ -385,12 +385,13 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
 
                        for (i=0; i<prop->len; i++) {
                                if (prop->subtype == IDP_FLOAT) {
-                                               PyList_SetItem(seq, i,
+                                       PyList_SET_ITEM(seq, i,
                                                PyFloat_FromDouble(((float*)prop->data.pointer)[i]));
                                } else if (prop->subtype == IDP_DOUBLE) {
-                                               PyList_SetItem(seq, i,
+                                       PyList_SET_ITEM(seq, i,
                                                PyFloat_FromDouble(((double*)prop->data.pointer)[i]));
-                               } else  { PyList_SetItem(seq, i,
+                               } else  {
+                                       PyList_SET_ITEM(seq, i,
                                                  PyLong_FromLong(((int*)prop->data.pointer)[i]));
                                }
                        }
@@ -470,79 +471,101 @@ static PyObject *BPy_IDGroup_IterItems(BPy_IDProperty *self)
        return (PyObject*) iter;
 }
 
-static PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
+/* utility function */
+static BPy_IDGroup_CorrectListLen(IDProperty *prop, PyObject *seq, int len)
 {
-       PyObject *seq = PyList_New(self->prop->len);
-       IDProperty *loop;
        int i, j;
 
-       if (!seq) {
-               PyErr_SetString( PyExc_RuntimeError, "PyList_New() failed" );
-               return NULL;
-       }
-
-       for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++)
-               PyList_SetItem(seq, i, PyUnicode_FromString(loop->name));
+       printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys/Values/Items!\n");
 
-       if (i != self->prop->len) {
-               printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys!\n");
+       /*fill rest of list with valid references to None*/
+       for (j=i; j<prop->len; j++) {
+               Py_INCREF(Py_None);
+               PyList_SET_ITEM(seq, j, Py_None);
+       }
 
-               /*fill rest of list with valid references to None*/
-               for (j=i; j<self->prop->len; j++) {
-                       Py_INCREF(Py_None);
-                       PyList_SetItem(seq, j, Py_None);
-               }
+       /*set correct group length*/
+       prop->len = i;
+}
 
-               /*set correct group length*/
-               self->prop->len = i;
+PyObject *BPy_Wrap_GetKeys(IDProperty *prop)
+{
+       PyObject *seq = PyList_New(prop->len);
+       IDProperty *loop;
+       int i;
 
-               /*free the list*/
-               Py_DECREF(seq);
+       for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++)
+               PyList_SET_ITEM(seq, i, PyUnicode_FromString(loop->name));
 
+       if (i != prop->len) {
+               BPy_IDGroup_CorrectListLen(prop, seq, i);
+               Py_DECREF(seq); /*free the list*/
                /*call self again*/
-               return BPy_IDGroup_GetKeys(self);
+               return BPy_Wrap_GetKeys(prop);
        }
 
        return seq;
 }
 
-static PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self)
+PyObject *BPy_Wrap_GetValues(ID *id, IDProperty *prop)
 {
-       PyObject *seq = PyList_New(self->prop->len);
+       PyObject *seq = PyList_New(prop->len);
        IDProperty *loop;
-       int i, j;
+       int i;
 
-       if (!seq) {
-               PyErr_SetString( PyExc_RuntimeError, "PyList_New() failed" );
-               return NULL;
+       for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) {
+               PyList_SET_ITEM(seq, i, BPy_IDGroup_WrapData(id, loop));
        }
 
-       for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++) {
-               PyList_SetItem(seq, i, BPy_IDGroup_WrapData(self->id, loop));
+       if (i != prop->len) {
+               BPy_IDGroup_CorrectListLen(prop, seq, i);
+               Py_DECREF(seq); /*free the list*/
+               /*call self again*/
+               return BPy_Wrap_GetValues(id, prop);
        }
 
-       if (i != self->prop->len) {
-               printf("ID Property Error found and corrected in BPy_IDGroup_GetValues!\n");
-
-               /*fill rest of list with valid references to None*/
-               for (j=i; j<self->prop->len; j++) {
-                       Py_INCREF(Py_None);
-                       PyList_SetItem(seq, j, Py_None);
-               }
+       return seq;
+}
 
-               /*set correct group length*/
-               self->prop->len = i;
+PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop)
+{
+       PyObject *seq = PyList_New(prop->len);
+       IDProperty *loop;
+       int i;
 
-               /*free the old list*/
-               Py_DECREF(seq);
+       for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) {
+               PyObject *item= PyTuple_New(2);
+               PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(loop->name));
+               PyTuple_SET_ITEM(item, 1, BPy_IDGroup_WrapData(id, loop));
+               PyList_SET_ITEM(seq, i, item);
+       }
 
+       if (i != prop->len) {
+               BPy_IDGroup_CorrectListLen(prop, seq, i);
+               Py_DECREF(seq); /*free the list*/
                /*call self again*/
-               return BPy_IDGroup_GetValues(self);
+               return BPy_Wrap_GetItems(id, prop);
        }
 
        return seq;
 }
 
+
+static PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
+{
+       return BPy_Wrap_GetKeys(self->prop);
+}
+
+static PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self)
+{
+       return BPy_Wrap_GetValues(self->id, self->prop);
+}
+
+static PyObject *BPy_IDGroup_GetItems(BPy_IDProperty *self)
+{
+       return BPy_Wrap_GetItems(self->id, self->prop);
+}
+
 static int BPy_IDGroup_Contains(BPy_IDProperty *self, PyObject *value)
 {
        char *name = _PyUnicode_AsString(value);
@@ -587,6 +610,8 @@ static struct PyMethodDef BPy_IDGroup_methods[] = {
                "get the keys associated with this group as a list of strings."},
        {"values", (PyCFunction)BPy_IDGroup_GetValues, METH_NOARGS,
                "get the values associated with this group."},
+       {"items", (PyCFunction)BPy_IDGroup_GetItems, METH_NOARGS,
+               "get the items associated with this group."},
        {"update", (PyCFunction)BPy_IDGroup_Update, METH_O,
                "updates the values in the group with the values of another or a dict."},
        {"convert_to_pyobject", (PyCFunction)BPy_IDGroup_ConvertToPy, METH_NOARGS,
@@ -902,16 +927,15 @@ static PyObject *IDGroup_Iter_repr(BPy_IDGroup_Iter *self)
 static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self)
 {
        IDProperty *cur=NULL;
-       PyObject *tmpval;
        PyObject *ret;
 
        if (self->cur) {
                cur = self->cur;
                self->cur = self->cur->next;
                if (self->mode == IDPROP_ITER_ITEMS) {
-                       tmpval = BPy_IDGroup_WrapData(self->group->id, cur);
-                       ret = Py_BuildValue("[s, O]", cur->name, tmpval);
-                       Py_DECREF(tmpval);
+                       ret = PyTuple_New(2);
+                       PyTuple_SET_ITEM(ret, 0, PyUnicode_FromString(cur->name));
+                       PyTuple_SET_ITEM(ret, 1, BPy_IDGroup_WrapData(self->group->id, cur));
                        return ret;
                } else {
                        return PyUnicode_FromString(cur->name);
index e78c9ed044cfbfd385010e4bda304758f3987be3..43b13eac377358681d516042beb56f20d60318fd 100644 (file)
@@ -49,8 +49,14 @@ typedef struct BPy_IDGroup_Iter {
 } BPy_IDGroup_Iter;
 
 PyObject *BPy_Wrap_IDProperty(struct ID *id, struct IDProperty *prop, struct IDProperty *parent);
+PyObject *BPy_Wrap_GetKeys(IDProperty *prop);
+PyObject *BPy_Wrap_GetValues(ID *id, IDProperty *prop);
+PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop);
+
+
 PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop );
 char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObject *ob);
+
 void IDProp_Init_Types(void);
 
 #define IDPROP_ITER_KEYS       0
index 66ed817987df7ab0f4acc1f2f8e28046aba782ba..fa45da6f28b7c39cc1d6de24969d8486c93bcac4 100644 (file)
@@ -1262,6 +1262,58 @@ static PyMappingMethods pyrna_struct_as_mapping = {
        ( objobjargproc ) pyrna_struct_ass_subscript,   /* mp_ass_subscript */
 };
 
+static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
+{
+       IDProperty *group;
+
+       if(RNA_struct_idproperties_check(&self->ptr)==0) {
+               PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+               return NULL;
+       }
+
+       group= RNA_struct_idproperties(&self->ptr, 0);
+
+       if(group==NULL)
+               return PyList_New(0);
+
+       return BPy_Wrap_GetKeys(group);
+}
+
+static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
+{
+       IDProperty *group;
+
+       if(RNA_struct_idproperties_check(&self->ptr)==0) {
+               PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+               return NULL;
+       }
+
+       group= RNA_struct_idproperties(&self->ptr, 0);
+
+       if(group==NULL)
+               return PyList_New(0);
+
+       return BPy_Wrap_GetItems(self->ptr.id.data, group);
+}
+
+
+static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
+{
+       IDProperty *group;
+
+       if(RNA_struct_idproperties_check(&self->ptr)==0) {
+               PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+               return NULL;
+       }
+
+       group= RNA_struct_idproperties(&self->ptr, 0);
+
+       if(group==NULL)
+               return PyList_New(0);
+
+       return BPy_Wrap_GetValues(self->ptr.id.data, group);
+}
+
 static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args)
 {
        char *path, *path_full;
@@ -2062,6 +2114,11 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
 
 static struct PyMethodDef pyrna_struct_methods[] = {
 
+       /* only for PointerRNA's with ID'props */
+       {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, NULL},
+       {"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, NULL},
+       {"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, NULL},
+
        /* 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},