diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-01-14 00:44:18 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-01-14 00:44:18 +0300 |
commit | c8df192de6710c280c82ae39a3dc5de851af4c70 (patch) | |
tree | 2c6ba93c3255898942126d3134cbdf9702b1196d /source/blender/python | |
parent | 5bdb576d3d097cc5ad09a93a6ca2ece4a7622efb (diff) |
misc python api improvements
- rna array parsing was using PySequence_Size() in a loop, this can be slow to run so only call once.
- assigning a single value to a multi-dimensional array was missing type check.
- improve exception messages for rna array type errors.
- simplify vector slice assignment by using mathutils_array_parse(...)
Diffstat (limited to 'source/blender/python')
-rw-r--r-- | source/blender/python/generic/mathutils_vector.c | 34 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna_array.c | 25 |
2 files changed, 23 insertions, 36 deletions
diff --git a/source/blender/python/generic/mathutils_vector.c b/source/blender/python/generic/mathutils_vector.c index cc9f9d32819..b5ac197abee 100644 --- a/source/blender/python/generic/mathutils_vector.c +++ b/source/blender/python/generic/mathutils_vector.c @@ -832,48 +832,28 @@ static PyObject *Vector_slice(VectorObject *self, int begin, int end) static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject * seq) { - int i, y, size = 0; - float vec[4], scalar; - PyObject *v; + int y, size = 0; + float vec[MAX_DIMENSIONS]; if(!BaseMath_ReadCallback(self)) return -1; - + CLAMP(begin, 0, self->size); - if (end<0) end= self->size+end+1; CLAMP(end, 0, self->size); begin = MIN2(begin,end); - size = PySequence_Size(seq); - if(size != (end - begin)){ - PyErr_SetString(PyExc_TypeError, "vector[begin:end] = []: size mismatch in slice assignment"); + size = (end - begin); + if(mathutils_array_parse(vec, size, size, seq, "vector[begin:end] = [...]:") == -1) return -1; - } - for (i = 0; i < size; i++) { - v = PySequence_GetItem(seq, i); - if (v == NULL) { /* Failed to read sequence */ - PyErr_SetString(PyExc_RuntimeError, "vector[begin:end] = []: unable to read sequence"); - return -1; - } - - if((scalar=PyFloat_AsDouble(v)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */ - Py_DECREF(v); - PyErr_SetString(PyExc_TypeError, "vector[begin:end] = []: sequence argument not a number"); - return -1; - } - - vec[i] = scalar; - Py_DECREF(v); - } /*parsed well - now set in vector*/ for(y = 0; y < size; y++){ self->vec[begin + y] = vec[y]; } - + if(!BaseMath_WriteCallback(self)) return -1; - + return 0; } /*------------------------NUMERIC PROTOCOLS---------------------- diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c index f3b3615793b..32efa387196 100644 --- a/source/blender/python/intern/bpy_rna_array.c +++ b/source/blender/python/intern/bpy_rna_array.c @@ -56,15 +56,15 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[] /* not the last dimension */ if (dim + 1 < totdim) { /* check that a sequence contains dimsize[dim] items */ - - for (i= 0; i < PySequence_Size(seq); i++) { + const int seq_size= PySequence_Size(seq); + for (i= 0; i < seq_size; i++) { PyObject *item; int ok= 1; item= PySequence_GetItem(seq, i); if (!PySequence_Check(item)) { /* BLI_snprintf(error_str, error_str_size, "expected a sequence of %s", item_type_str); */ - PyErr_Format(PyExc_TypeError, "%s expected a sequence of %s", error_prefix, item_type_str); + PyErr_Format(PyExc_TypeError, "%s expected a sequence of %s, not %s", error_prefix, item_type_str, Py_TYPE(item)->tp_name); ok= 0; } /* arr[3][4][5] @@ -89,14 +89,15 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[] } else { /* check that items are of correct type */ - for (i= 0; i < PySequence_Size(seq); i++) { + const int seq_size= PySequence_Size(seq); + for (i= 0; i < seq_size; i++) { PyObject *item= PySequence_GetItem(seq, i); if (!check_item_type(item)) { Py_DECREF(item); /* BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); */ - PyErr_Format(PyExc_TypeError, "sequence items should be of type %s", item_type_str); + PyErr_Format(PyExc_TypeError, "expected sequence items of type %s, not %s", item_type_str, Py_TYPE(item)->tp_name); return 0; } @@ -113,8 +114,9 @@ static int count_items(PyObject *seq) int totitem= 0; if (PySequence_Check(seq)) { + const int seq_size= PySequence_Size(seq); int i; - for (i= 0; i < PySequence_Size(seq); i++) { + for (i= 0; i < seq_size; i++) { PyObject *item= PySequence_GetItem(seq, i); totitem += count_items(item); Py_DECREF(item); @@ -183,7 +185,7 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA if (tot != len) { /* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */ - PyErr_Format(PyExc_ValueError, "%s sequence must have %d items total", error_prefix, len); + PyErr_Format(PyExc_ValueError, "%s sequence must have %d items total, not %d", error_prefix, len, tot); return 0; } } @@ -227,8 +229,9 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int { unsigned int i; int totdim= RNA_property_array_dimension(ptr, prop, NULL); + const int seq_size= PySequence_Size(seq); - for (i= 0; i < PySequence_Size(seq); i++) { + for (i= 0; i < seq_size; i++) { PyObject *item= PySequence_GetItem(seq, i); if (dim + 1 < totdim) { @@ -310,6 +313,10 @@ static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, i index += arrayoffset; if(lvalue_dim == totdim) { /* single item, assign directly */ + if(!check_item_type(py)) { + PyErr_Format(PyExc_TypeError, "%s expected a %s type, not %s", error_prefix, item_type_str, Py_TYPE(py)->tp_name); + return 0; + } copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index); } else { @@ -342,7 +349,7 @@ static void py_to_bool(PyObject *py, char *data) static int py_float_check(PyObject *py) { /* accept both floats and integers */ - return PyFloat_Check(py) || PyLong_Check(py); + return PyNumber_Check(py); } static int py_int_check(PyObject *py) |