Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[blender.git] / source / blender / python / intern / bpy_rna.c
index dd6bc35..3679d74 100644 (file)
@@ -130,70 +130,6 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
        (BaseMathSetIndexFunc)  NULL
 };
 
-PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
-{
-       PyObject *ret= NULL;
-
-#ifdef USE_MATHUTILS
-       int type, subtype, totdim;
-       int len;
-
-       len= RNA_property_array_length(ptr, prop);
-       type= RNA_property_type(prop);
-       subtype= RNA_property_subtype(prop);
-       totdim= RNA_property_array_dimension(ptr, prop, NULL);
-
-       if (type != PROP_FLOAT) return NULL;
-
-       if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
-               ret = pyrna_prop_CreatePyObject(ptr, prop);
-
-               switch(RNA_property_subtype(prop)) {
-               case PROP_TRANSLATION:
-               case PROP_DIRECTION:
-               case PROP_VELOCITY:
-               case PROP_ACCELERATION:
-               case PROP_XYZ:
-                       if(len>=2 && len <= 4) {
-                               PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE);
-                               Py_DECREF(ret); /* the vector owns now */
-                               ret= vec_cb; /* return the vector instead */
-                       }
-                       break;
-               case PROP_MATRIX:
-                       if(len==16) {
-                               PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
-                               Py_DECREF(ret); /* the matrix owns now */
-                               ret= mat_cb; /* return the matrix instead */
-                       }
-                       else if (len==9) {
-                               PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
-                               Py_DECREF(ret); /* the matrix owns now */
-                               ret= mat_cb; /* return the matrix instead */
-                       }
-                       break;
-               case PROP_EULER:
-               case PROP_QUATERNION:
-                       if(len==3) { /* euler */
-                               PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
-                               Py_DECREF(ret); /* the matrix owns now */
-                               ret= eul_cb; /* return the matrix instead */
-                       }
-                       else if (len==4) {
-                               PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
-                               Py_DECREF(ret); /* the matrix owns now */
-                               ret= quat_cb; /* return the matrix instead */
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-#endif
-
-       return ret;
-}
-
 #endif
 
 static StructRNA *pyrna_struct_as_srna(PyObject *self);
@@ -208,64 +144,25 @@ static int pyrna_prop_compare( BPy_PropertyRNA * a, BPy_PropertyRNA * b )
        return (a->prop==b->prop && a->ptr.data==b->ptr.data ) ? 0 : -1;
 }
 
-static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
+/* For some reason python3 needs these :/ */
+static PyObject *pyrna_struct_richcmp(BPy_StructRNA * a, BPy_StructRNA * b, int op)
 {
-       PyObject *res;
-       int ok= -1; /* zero is true */
-
-       if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b))
-               ok= pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b);
-
-       switch (op) {
-       case Py_NE:
-               ok = !ok; /* pass through */
-       case Py_EQ:
-               res = ok ? Py_False : Py_True;
-               break;
-
-       case Py_LT:
-       case Py_LE:
-       case Py_GT:
-       case Py_GE:
-               res = Py_NotImplemented;
-               break;
-       default:
-               PyErr_BadArgument();
-               return NULL;
+       int cmp_result= -1; /* assume false */
+       if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) {
+               cmp_result= pyrna_struct_compare(a, b);
        }
 
-       Py_INCREF(res);
-       return res;
+       return Py_CmpToRich(op, cmp_result);
 }
 
-static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
+static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, int op)
 {
-       PyObject *res;
-       int ok= -1; /* zero is true */
-
-       if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b))
-               ok= pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b);
-
-       switch (op) {
-       case Py_NE:
-               ok = !ok; /* pass through */
-       case Py_EQ:
-               res = ok ? Py_False : Py_True;
-               break;
-
-       case Py_LT:
-       case Py_LE:
-       case Py_GT:
-       case Py_GE:
-               res = Py_NotImplemented;
-               break;
-       default:
-               PyErr_BadArgument();
-               return NULL;
+       int cmp_result= -1; /* assume false */
+       if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) {
+               cmp_result= pyrna_prop_compare(a, b);
        }
 
-       Py_INCREF(res);
-       return res;
+       return Py_CmpToRich(op, cmp_result);
 }
 
 /*----------------------repr--------------------------------------------*/
@@ -345,14 +242,86 @@ static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
        return result;
 }
 
+static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix)
+{
+       char *param= _PyUnicode_AsString(item);
+
+       if (param==NULL) {
+               char *enum_str= pyrna_enum_as_string(ptr, prop);
+               PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str);
+               MEM_freeN(enum_str);
+               return 0;
+       } else {
+               if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) {
+                       char *enum_str= pyrna_enum_as_string(ptr, prop);
+                       PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
+                       MEM_freeN(enum_str);
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
 PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
 {
        PyObject *ret;
        int type = RNA_property_type(prop);
-       int len = RNA_property_array_length(ptr, prop);
+       int len = RNA_property_array_length(prop);
 
        if (len > 0) {
-               return pyrna_py_from_array(ptr, prop);
+               /* resolve the array from a new pytype */
+               PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop);
+               
+#ifdef USE_MATHUTILS
+
+               /* return a mathutils vector where possible */
+               if(RNA_property_type(prop)==PROP_FLOAT) {
+                       switch(RNA_property_subtype(prop)) {
+                       case PROP_TRANSLATION:
+                       case PROP_DIRECTION:
+                       case PROP_VELOCITY:
+                       case PROP_ACCELERATION:
+                       case PROP_XYZ:
+                               if(len>=2 && len <= 4) {
+                                       PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE);
+                                       Py_DECREF(ret); /* the vector owns now */
+                                       ret= vec_cb; /* return the vector instead */
+                               }
+                               break;
+                       case PROP_MATRIX:
+                               if(len==16) {
+                                       PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
+                                       Py_DECREF(ret); /* the matrix owns now */
+                                       ret= mat_cb; /* return the matrix instead */
+                               }
+                               else if (len==9) {
+                                       PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
+                                       Py_DECREF(ret); /* the matrix owns now */
+                                       ret= mat_cb; /* return the matrix instead */
+                               }
+                               break;
+                       case PROP_EULER:
+                       case PROP_QUATERNION:
+                               if(len==3) { /* euler */
+                                       PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
+                                       Py_DECREF(ret); /* the matrix owns now */
+                                       ret= eul_cb; /* return the matrix instead */
+                               }
+                               else if (len==4) {
+                                       PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
+                                       Py_DECREF(ret); /* the matrix owns now */
+                                       ret= quat_cb; /* return the matrix instead */
+                               }
+                               break;
+                       default:
+                               break;
+                       }
+               }
+
+#endif
+               
+               return ret;
        }
        
        /* see if we can coorce into a python type - PropertyType */
@@ -521,32 +490,127 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
 {
        /* XXX hard limits should be checked here */
        int type = RNA_property_type(prop);
-       int len = RNA_property_array_length(ptr, prop);
+       int len = RNA_property_array_length(prop);
        
        if (len > 0) {
-               /* char error_str[512]; */
-               int ok= 1;
-
+               PyObject *item;
+               int py_len = -1;
+               int i;
+               
 #ifdef USE_MATHUTILS
                if(MatrixObject_Check(value)) {
                        MatrixObject *mat = (MatrixObject*)value;
                        if(!BaseMath_ReadCallback(mat))
                                return -1;
+
+                       py_len = mat->rowSize * mat->colSize;
                } else /* continue... */
 #endif
-               if (!PySequence_Check(value)) {
+               if (PySequence_Check(value)) {
+                       py_len= (int)PySequence_Length(value);
+               }
+               else {
                        PyErr_Format(PyExc_TypeError, "%.200s RNA array assignment expected a sequence instead of %.200s instance.", error_prefix, Py_TYPE(value)->tp_name);
                        return -1;
                }
                /* done getting the length */
-               ok= pyrna_py_to_array(ptr, prop, data, value, error_prefix);
-
-               if (!ok) {
-                       /* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */
+               
+               if (py_len != len) {
+                       PyErr_Format(PyExc_TypeError, "%.200s python sequence length %d did not match the RNA array length %d.", error_prefix, py_len, len);
                        return -1;
                }
-       }
-       else {
+               
+               /* for arrays we have a limited number of types */
+               switch (type) {
+               case PROP_BOOLEAN:
+               {
+                       int *param_arr;
+                       if(data)        param_arr= (int*)data;
+                       else            param_arr= MEM_mallocN(sizeof(int) * len, "pyrna bool array");
+
+                       
+                       /* collect the variables before assigning, incase one of them is incorrect */
+                       for (i=0; i<len; i++) {
+                               item = PySequence_GetItem(value, i);
+                               param_arr[i] = PyObject_IsTrue( item );
+                               Py_DECREF(item);
+                               
+                               if (param_arr[i] < 0) {
+                                       if(data==NULL)
+                                               MEM_freeN(param_arr);
+                                       PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence is not a boolean", error_prefix);
+                                       return -1;
+                               }
+                       }
+                       if(data==NULL) {
+                               RNA_property_boolean_set_array(ptr, prop, param_arr);
+                               MEM_freeN(param_arr);
+                       }
+
+                       break;
+               }
+               case PROP_INT:
+               {
+                       int *param_arr;
+                       if(data)        param_arr= (int*)data;
+                       else            param_arr= MEM_mallocN(sizeof(int) * len, "pyrna int array");
+
+                       
+                       /* collect the variables */
+                       for (i=0; i<len; i++) {
+                               item = PySequence_GetItem(value, i);
+                               param_arr[i] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */
+                               Py_DECREF(item);
+                       }
+                       
+                       if (PyErr_Occurred()) {
+                               if(data==NULL)
+                                       MEM_freeN(param_arr);
+                               PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence could not be used as an int", error_prefix);
+                               return -1;
+                       }
+                       if(data==NULL) {
+                               RNA_property_int_set_array(ptr, prop, param_arr);
+                               MEM_freeN(param_arr);
+                       }
+                       break;
+               }
+               case PROP_FLOAT:
+               {
+                       float *param_arr;
+                       if(data)        param_arr = (float*)data;
+                       else            param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float array");
+
+
+#ifdef USE_MATHUTILS
+                       if(MatrixObject_Check(value) && RNA_property_subtype(prop) == PROP_MATRIX) {
+                               MatrixObject *mat = (MatrixObject*)value;
+                               memcpy(param_arr, mat->contigPtr, sizeof(float) * len);
+                       } else /* continue... */
+#endif
+                       {
+                               /* collect the variables */
+                               for (i=0; i<len; i++) {
+                                       item = PySequence_GetItem(value, i);
+                                       param_arr[i] = (float)PyFloat_AsDouble(item); /* deal with any errors later */
+                                       Py_DECREF(item);
+                               }
+                       }
+
+                       if (PyErr_Occurred()) {
+                               if(data==NULL)
+                                       MEM_freeN(param_arr);
+                               PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence could not be used as a float", error_prefix);
+                               return -1;
+                       }
+                       if(data==NULL) {
+                               RNA_property_float_set_array(ptr, prop, param_arr);                             
+                               MEM_freeN(param_arr);
+                       }
+                       break;
+               }
+               }
+       } else {
                /* Normal Property (not an array) */
                
                /* see if we can coorce into a python type - PropertyType */
@@ -603,25 +667,34 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
                }
                case PROP_ENUM:
                {
-                       char *param = _PyUnicode_AsString(value);
-                       
-                       if (param==NULL) {
+                       int val, i;
+
+                       if (PyUnicode_Check(value)) {
+                               if (!pyrna_string_to_enum(value, ptr, prop, &val, error_prefix))
+                                       return -1;
+                       }
+                       else if (PyTuple_Check(value)) {
+                               /* tuple of enum items, concatenate all values with OR */
+                               val= 0;
+                               for (i= 0; i < PyTuple_Size(value); i++) {
+                                       int tmpval;
+
+                                       /* PyTuple_GET_ITEM returns a borrowed reference */
+                                       if (!pyrna_string_to_enum(PyTuple_GET_ITEM(value, i), ptr, prop, &tmpval, error_prefix))
+                                               return -1;
+
+                                       val |= tmpval;
+                               }
+                       }
+                       else {
                                char *enum_str= pyrna_enum_as_string(ptr, prop);
-                               PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str);
+                               PyErr_Format(PyExc_TypeError, "%.200s expected a string enum or a tuple of strings in (%.200s)", error_prefix, enum_str);
                                MEM_freeN(enum_str);
                                return -1;
-                       } else {
-                               int val;
-                               if (RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, &val)) {
-                                       if(data)        *((int*)data)= val;
-                                       else            RNA_property_enum_set(ptr, prop, val);
-                               } else {
-                                       char *enum_str= pyrna_enum_as_string(ptr, prop);
-                                       PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
-                                       MEM_freeN(enum_str);
-                                       return -1;
-                               }
                        }
+
+                       if(data)        *((int*)data)= val;
+                       else            RNA_property_enum_set(ptr, prop, val);
                        
                        break;
                }
@@ -735,84 +808,82 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
        return 0;
 }
 
-static PyObject * pyrna_prop_to_py_index(BPy_PropertyRNA *self, int index)
+static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int index)
 {
-       return pyrna_py_from_array_index(self, index);
+       PyObject *ret;
+       int type = RNA_property_type(prop);
+       
+       /* see if we can coorce into a python type - PropertyType */
+       switch (type) {
+       case PROP_BOOLEAN:
+               ret = PyBool_FromLong( RNA_property_boolean_get_index(ptr, prop, index) );
+               break;
+       case PROP_INT:
+               ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get_index(ptr, prop, index) );
+               break;
+       case PROP_FLOAT:
+               ret = PyFloat_FromDouble( RNA_property_float_get_index(ptr, prop, index) );
+               break;
+       default:
+               PyErr_SetString(PyExc_AttributeError, "not an array type");
+               ret = NULL;
+               break;
+       }
+       
+       return ret;
 }
 
-static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *value)
+static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index, PyObject *value)
 {
        int ret = 0;
-       int totdim;
-       PointerRNA *ptr= &self->ptr;
-       PropertyRNA *prop= self->prop;
        int type = RNA_property_type(prop);
-
-       totdim= RNA_property_array_dimension(ptr, prop, NULL);
-
-       if (totdim > 1) {
-               /* char error_str[512]; */
-               if (!pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "")) {
-                       /* PyErr_SetString(PyExc_AttributeError, error_str); */
-                       ret= -1;
+       
+       /* see if we can coorce into a python type - PropertyType */
+       switch (type) {
+       case PROP_BOOLEAN:
+       {
+               int param = PyObject_IsTrue( value );
+               
+               if( param < 0 ) {
+                       PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
+                       ret = -1;
+               } else {
+                       RNA_property_boolean_set_index(ptr, prop, index, param);
                }
+               break;
        }
-       else {
-               /* see if we can coorce into a python type - PropertyType */
-               switch (type) {
-               case PROP_BOOLEAN:
-                       {
-                               int param = PyObject_IsTrue( value );
-               
-                               if( param < 0 ) {
-                                       PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
-                                       ret = -1;
-                               } else {
-                                       RNA_property_boolean_set_index(ptr, prop, index, param);
-                               }
-                               break;
-                       }
-               case PROP_INT:
-                       {
-                               int param = PyLong_AsSsize_t(value);
-                               if (PyErr_Occurred()) {
-                                       PyErr_SetString(PyExc_TypeError, "expected an int type");
-                                       ret = -1;
-                               } else {
-                                       RNA_property_int_set_index(ptr, prop, index, param);
-                               }
-                               break;
-                       }
-               case PROP_FLOAT:
-                       {
-                               float param = PyFloat_AsDouble(value);
-                               if (PyErr_Occurred()) {
-                                       PyErr_SetString(PyExc_TypeError, "expected a float type");
-                                       ret = -1;
-                               } else {
-                                       RNA_property_float_set_index(ptr, prop, index, param);
-                               }
-                               break;
-                       }
-               default:
-                       PyErr_SetString(PyExc_AttributeError, "not an array type");
+       case PROP_INT:
+       {
+               int param = PyLong_AsSsize_t(value);
+               if (PyErr_Occurred()) {
+                       PyErr_SetString(PyExc_TypeError, "expected an int type");
                        ret = -1;
-                       break;
+               } else {
+                       RNA_property_int_set_index(ptr, prop, index, param);
                }
+               break;
+       }
+       case PROP_FLOAT:
+       {
+               float param = PyFloat_AsDouble(value);
+               if (PyErr_Occurred()) {
+                       PyErr_SetString(PyExc_TypeError, "expected a float type");
+                       ret = -1;
+               } else {
+                       RNA_property_float_set_index(ptr, prop, index, param);
+               }
+               break;
+       }
+       default:
+               PyErr_SetString(PyExc_AttributeError, "not an array type");
+               ret = -1;
+               break;
        }
        
        return ret;
 }
 
 //---------------sequence-------------------------------------------
-static int pyrna_prop_array_length(BPy_PropertyRNA *self)
-{
-       if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
-               return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
-       else
-               return RNA_property_array_length(&self->ptr, self->prop);
-}
-
 static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
 {
        Py_ssize_t len;
@@ -820,10 +891,10 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
        if (RNA_property_type(self->prop) == PROP_COLLECTION) {
                len = RNA_property_collection_length(&self->ptr, self->prop);
        } else {
-               len = pyrna_prop_array_length(self);
+               len = RNA_property_array_length(self->prop);
                
                if (len==0) { /* not an array*/
-                       PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
+                       PyErr_SetString(PyExc_AttributeError, "len() only available for collection RNA types");
                        return -1;
                }
        }
@@ -844,15 +915,14 @@ static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynu
        PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
        return NULL;
 }
-
 static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum)
 {
-       int len= pyrna_prop_array_length(self);
+       int len= RNA_property_array_length(self->prop);
 
        if(keynum < 0) keynum += len;
 
        if(keynum >= 0 && keynum < len)
-               return pyrna_prop_to_py_index(self, keynum);
+               return pyrna_prop_to_py_index(&self->ptr, self->prop, keynum);
 
        PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
        return NULL;
@@ -899,7 +969,7 @@ static PyObject *prop_subscript_array_slice(BPy_PropertyRNA * self, int start, i
        start = MIN2(start,stop); /* values are clamped from PySlice_GetIndicesEx */
 
        for(count = start; count < stop; count++)
-               PyList_SetItem(list, count - start, pyrna_prop_to_py_index(self, count));
+               PyList_SetItem(list, count - start, pyrna_prop_to_py_index(&self->ptr, self->prop, count));
 
        return list;
 }
@@ -952,8 +1022,8 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA * self, PyObject *key)
                return prop_subscript_array_int(self, PyLong_AsSsize_t(key));
        }
        else if (PySlice_Check(key)) {
+               int len= RNA_property_array_length(self->prop);
                Py_ssize_t start, stop, step, slicelength;
-               int len = pyrna_prop_array_length(self);
 
                if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
                        return NULL;
@@ -979,12 +1049,13 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
 {
        if (RNA_property_type(self->prop) == PROP_COLLECTION) {
                return prop_subscript_collection(self, key);
-       } else if (RNA_property_array_length(&self->ptr, self->prop)) { /* zero length means its not an array */
+       } else if (RNA_property_array_length(self->prop)) { /* arrays are currently fixed length, zero length means its not an array */
                return prop_subscript_array(self, key);
-       } 
+       } else {
+               PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
+               return NULL;
+       }
 
-       PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
-       return NULL;
 }
 
 static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int end, PyObject *value)
@@ -995,7 +1066,7 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int
        begin = MIN2(begin,end);
 
        for(count = begin; count < end; count++) {
-               if(pyrna_py_to_prop_index(self, count - begin, value) == -1) {
+               if(pyrna_py_to_prop_index(&self->ptr, self->prop, count - begin, value) == -1) {
                        /* TODO - this is wrong since some values have been assigned... will need to fix that */
                        return -1; /* pyrna_struct_CreatePyObject should set the error */
                }
@@ -1006,12 +1077,13 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int
 
 static int prop_subscript_ass_array_int(BPy_PropertyRNA * self, int keynum, PyObject *value)
 {
-       int len= pyrna_prop_array_length(self);
+
+       int len= RNA_property_array_length(self->prop);
 
        if(keynum < 0) keynum += len;
 
        if(keynum >= 0 && keynum < len)
-               return pyrna_py_to_prop_index(self, keynum, value);
+               return pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value);
 
        PyErr_SetString(PyExc_IndexError, "out of range");
        return -1;
@@ -1040,7 +1112,7 @@ static int pyrna_prop_ass_subscript( BPy_PropertyRNA * self, PyObject *key, PyOb
                return prop_subscript_ass_array_int(self, i, value);
        }
        else if (PySlice_Check(key)) {
-               int len= RNA_property_array_length(&self->ptr, self->prop);
+               int len= RNA_property_array_length(self->prop);
                Py_ssize_t start, stop, step, slicelength;
 
                if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
@@ -1453,7 +1525,7 @@ static void foreach_attr_type(    BPy_PropertyRNA *self, char *attr,
        RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
                prop = RNA_struct_find_property(&itemptr, attr);
                *raw_type= RNA_property_raw_type(prop);
-               *attr_tot = RNA_property_array_length(&itemptr, prop);
+               *attr_tot = RNA_property_array_length(prop);
                *attr_signed= (RNA_property_subtype(prop)==PROP_UNSIGNED) ? FALSE:TRUE;
                break;
        }
@@ -1492,7 +1564,7 @@ static int foreach_parse_args(
                if (RNA_property_type(self->prop) == PROP_COLLECTION)
                        array_tot = RNA_property_collection_length(&self->ptr, self->prop);
                else
-                       array_tot = RNA_property_array_length(&self->ptr, self->prop);
+                       array_tot = RNA_property_array_length(self->prop);
 
 
                target_tot= array_tot * (*attr_tot);
@@ -1685,7 +1757,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
        
        if (ret==NULL) {
                /* collection did not work, try array */
-               int len = pyrna_prop_array_length(self);
+               int len = RNA_property_array_length(self->prop);
                
                if (len) {
                        int i;
@@ -1693,7 +1765,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
                        ret = PyList_New(len);
                        
                        for (i=0; i < len; i++) {
-                               PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
+                               PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(&self->ptr, self->prop, i));
                        }
                }
        }
@@ -1776,7 +1848,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
 {
        PyObject *ret;
        int type = RNA_property_type(prop);
-       int len = RNA_property_array_length(ptr, prop);
+       int len = RNA_property_array_length(prop);
 
        int a;
 
@@ -1784,7 +1856,9 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
                /* resolve the array from a new pytype */
                ret = PyTuple_New(len);
 
-               /* kazanbas: TODO make multidim sequences here */
+               /* for return values, data is a pointer to an array, not first element pointer */
+               if (RNA_property_flag(prop) & PROP_DYNAMIC_ARRAY)
+                       data = *(char**)(char*)data;
 
                switch (type) {
                case PROP_BOOLEAN:
@@ -2450,9 +2524,6 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
        
        pyrna->ptr = *ptr;
        pyrna->prop = prop;
-
-       pyrna->arraydim= 0;
-       pyrna->arrayoffset= 0;
                
        return ( PyObject * ) pyrna;
 }
@@ -2617,17 +2688,8 @@ PyObject *BPY_rna_props( void )
 
 static StructRNA *pyrna_struct_as_srna(PyObject *self)
 {
-       BPy_StructRNA *py_srna;
+       BPy_StructRNA *py_srna= (BPy_StructRNA*)PyObject_GetAttrString(self, "__rna__");
        StructRNA *srna;
-       
-       /* 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_XINCREF(py_srna);
-       }
-       
-       if(py_srna==NULL)
-               py_srna = (BPy_StructRNA*)PyObject_GetAttrString(self, "__rna__");
 
        if(py_srna==NULL) {
                PyErr_SetString(PyExc_SystemError, "internal error, self had no __rna__ attribute, should never happen.");
@@ -2902,12 +2964,12 @@ static StructRNA *pointer_type_from_py(PyObject *value)
 
        srna= srna_from_self(value);
        if(!srna) {
-               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup");
+               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup (1)");
                return NULL;
        }
 
        if(!RNA_struct_is_a(srna, &RNA_IDPropertyGroup)) {
-               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup");
+               PyErr_SetString(PyExc_SystemError, "expected an RNA type derived from IDPropertyGroup (3)");
                return NULL;
        }
 
@@ -2984,52 +3046,6 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
        return NULL;
 }
 
-static int deferred_register_props(PyObject *py_class, StructRNA *srna)
-{
-       PyObject *props, *dummy_args, *item;
-       int i;
-
-       props= PyObject_GetAttrString(py_class, "__props__");
-       
-       if(!props) {
-               PyErr_Clear();
-               return 1;
-       }
-
-       dummy_args = PyTuple_New(0);
-
-       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);
-
-                       if(py_ret) {
-                               Py_DECREF(py_ret);
-                       }
-                       else {
-                               Py_DECREF(dummy_args);
-                               return 0;
-                       }
-               }
-               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;
-}
-
 /*-------------------- Type Registration ------------------------*/
 
 static int rna_function_arg_count(FunctionRNA *func)
@@ -3390,9 +3406,6 @@ 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;
-
        Py_RETURN_NONE;
 }
 
@@ -3416,6 +3429,7 @@ PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class)
        
        /* get the context, so register callback can do necessary refreshes */
        C= BPy_GetContext();
+       
 
        /* call unregister */
        unreg(C, srna); /* calls bpy_class_free, this decref's py_class */