rna function api was overwriting useful errors with keyword errors.
[blender.git] / source / blender / python / intern / bpy_rna.c
index f2ffd5e0358eb85103efe6f3e777e6be7b438f82..50e32f34594a206de22b018bb53d1b36292af04e 100644 (file)
@@ -141,7 +141,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
        len= RNA_property_array_length(ptr, prop);
        type= RNA_property_type(prop);
        subtype= RNA_property_subtype(prop);
-       totdim= RNA_property_array_dimension(prop, NULL);
+       totdim= RNA_property_array_dimension(ptr, prop, NULL);
 
        if (type != PROP_FLOAT) return NULL;
 
@@ -349,9 +349,8 @@ 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);
 
-       if (len > 0) {
+       if (RNA_property_array_check(ptr, prop)) {
                return pyrna_py_from_array(ptr, prop);
        }
        
@@ -521,9 +520,10 @@ 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);
        
-       if (len > 0) {
+
+       if (RNA_property_array_check(ptr, prop)) {
+
                /* char error_str[512]; */
                int ok= 1;
 
@@ -628,17 +628,18 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
                case PROP_POINTER:
                {
                        StructRNA *ptype= RNA_property_pointer_type(ptr, prop);
+                       int flag = RNA_property_flag(prop);
 
                        if(!BPy_StructRNA_Check(value) && value != Py_None) {
-                               PointerRNA tmp;
-                               RNA_pointer_create(NULL, ptype, NULL, &tmp);
-                               PyErr_Format(PyExc_TypeError, "%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(tmp.type));
+                               PyErr_Format(PyExc_TypeError, "%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(ptype));
+                               return -1;
+                       } else if((flag & PROP_NEVER_NULL) && value == Py_None) {
+                               PyErr_Format(PyExc_TypeError, "property can't be assigned a None value");
                                return -1;
                        } else {
                                BPy_StructRNA *param= (BPy_StructRNA*)value;
                                int raise_error= FALSE;
                                if(data) {
-                                       int flag = RNA_property_flag(prop);
 
                                        if(flag & PROP_RNAPTR) {
                                                if(value == Py_None)
@@ -748,7 +749,7 @@ static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *va
        PropertyRNA *prop= self->prop;
        int type = RNA_property_type(prop);
 
-       totdim= RNA_property_array_dimension(prop, NULL);
+       totdim= RNA_property_array_dimension(ptr, prop, NULL);
 
        if (totdim > 1) {
                /* char error_str[512]; */
@@ -807,8 +808,8 @@ static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *va
 //---------------sequence-------------------------------------------
 static int pyrna_prop_array_length(BPy_PropertyRNA *self)
 {
-       if (RNA_property_array_dimension(self->prop, NULL) > 1)
-               return RNA_property_multidimensional_array_length(&self->ptr, self->prop, self->arraydim);
+       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);
 }
@@ -819,13 +820,11 @@ 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 {
+       } else if (RNA_property_array_check(&self->ptr, self->prop)) {
                len = pyrna_prop_array_length(self);
-               
-               if (len==0) { /* not an array*/
-                       PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
-                       return -1;
-               }
+       } else {
+               PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
+               len = -1; /* error value */
        }
        
        return len;
@@ -979,7 +978,7 @@ 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_check(&self->ptr, self->prop)) {
                return prop_subscript_array(self, key);
        } 
 
@@ -1681,32 +1680,32 @@ static  PyObject *pyrna_prop_foreach_set(BPy_PropertyRNA *self, PyObject *args)
 PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
 {
        /* Try get values from a collection */
-       PyObject *ret = pyrna_prop_values(self);
+       PyObject *ret;
+       PyObject *iter;
        
-       if (ret==NULL) {
-               /* collection did not work, try array */
+       if(RNA_property_array_check(&self->ptr, self->prop)) {
                int len = pyrna_prop_array_length(self);
+               int i;
+               PyErr_Clear();
+               ret = PyList_New(len);
                
-               if (len) {
-                       int i;
-                       PyErr_Clear();
-                       ret = PyList_New(len);
-                       
-                       for (i=0; i < len; i++) {
-                               PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
-                       }
+               for (i=0; i < len; i++) {
+                       PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
                }
        }
-       
-       if (ret) {
-               /* we know this is a list so no need to PyIter_Check */
-               PyObject *iter = PyObject_GetIter(ret); 
-               Py_DECREF(ret);
-               return iter;
+       else if ((ret = pyrna_prop_values(self))) {
+               /* do nothing */
+       }
+       else {
+               PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
+               return NULL;
        }
        
-       PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
-       return NULL;
+       
+       /* we know this is a list so no need to PyIter_Check */
+       iter = PyObject_GetIter(ret);
+       Py_DECREF(ret);
+       return iter;
 }
 
 static struct PyMethodDef pyrna_struct_methods[] = {
@@ -1776,11 +1775,12 @@ 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 a;
 
-       if(len > 0) {
+       if(RNA_property_array_check(ptr, prop)) {
+               int len = RNA_property_array_length(ptr, prop);
+
                /* resolve the array from a new pytype */
                ret = PyTuple_New(len);
 
@@ -1994,8 +1994,10 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
 
        /* Check if we gave args that dont exist in the function
         * printing the error is slow but it should only happen when developing.
-        * the if below is quick, checking if it passed less keyword args then we gave */
-       if(kw && (PyDict_Size(kw) > kw_tot)) {
+        * the if below is quick, checking if it passed less keyword args then we gave.
+        * (Dont overwrite the error if we have one, otherwise can skip important messages and confuse with args)
+        */
+       if(err == 0 && kw && (PyDict_Size(kw) > kw_tot)) {
                PyObject *key, *value;
                Py_ssize_t pos = 0;