From 18f3e5d69f7959afaf41a55a5e18cc0a0a2a0972 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 30 Nov 2008 03:52:07 +0000 Subject: [PATCH] PyRNA Can now assign RNA arrays from python lists of bools/ints/floats eg -> rna.scenes["Scene"].layer = [True] * 20 Also added exceptions when trying to set readonly properties. --- source/blender/python/intern/bpy_rna.c | 286 ++++++++++++++++--------- 1 file changed, 189 insertions(+), 97 deletions(-) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 991f6b9d04c..266ca665e50 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -131,111 +131,198 @@ static PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) { - int ret = 0; int type = RNA_property_type(ptr, prop); int len = RNA_property_array_length(ptr, prop); /* resolve path */ if (len > 0) { - /* resolve the array from a new pytype */ - PyErr_SetString(PyExc_TypeError, "array type, cant assign"); - return -1; - } - - /* see if we can coorce into a python type - PropertyType */ - switch (type) { - case PROP_BOOLEAN: - { - int param = PyObject_IsTrue( value ); + PyObject *item; + int i; - if( param == -1 ) { - PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1"); - ret = -1; - } else { - RNA_property_boolean_set(ptr, prop, param); + if (!PySequence_Check(value)) { + PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array."); + return -1; } - 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(ptr, prop, 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(ptr, prop, param); - } - break; - } - case PROP_STRING: - { - char *param = _PyUnicode_AsString(value); - if (param==NULL) { - PyErr_SetString(PyExc_TypeError, "expected a string type"); - ret = -1; - } else { - RNA_property_string_set(ptr, prop, param); + if ((int)PySequence_Length(value) != len) { + PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array."); + return -1; } - break; - } - case PROP_ENUM: - { - char *param = _PyUnicode_AsString(value); - if (param==NULL) { - PyErr_SetString(PyExc_TypeError, "expected a string type"); - ret = -1; - } else { - const EnumPropertyItem *item; - int totitem, i, val; + /* for arrays we have a limited number of types */ + switch (type) { + case PROP_BOOLEAN: + { + signed char *param_arr = MEM_mallocN(sizeof(char) * len, "pyrna bool array"); - RNA_property_enum_items(ptr, prop, &item, &totitem); - - for (i=0; iptr, self->prop)) { + PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, self->prop), RNA_struct_identifier(&self->ptr) ); + return -1; + } + if (PyUnicode_Check(key)) { keyname = _PyUnicode_AsString(key); } else if (PyLong_Check(key)) { @@ -480,20 +572,20 @@ static PyObject *pyrna_struct_getattr( BPy_StructRNA * self, char *name ) //--------------- setattr------------------------------------------- static int pyrna_struct_setattr( BPy_StructRNA * self, char *name, PyObject * value ) { - int ret = 0; - PropertyRNA *prop; - - prop = RNA_struct_find_property(&self->ptr, name); + PropertyRNA *prop = RNA_struct_find_property(&self->ptr, name); if (prop==NULL) { PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name); - ret = -1; - } else { - /* pyrna_py_to_prop sets its own exceptions */ - ret = pyrna_py_to_prop(&self->ptr, prop, value); - } + return -1; + } - return ret; + if (!RNA_property_editable(&self->ptr, prop)) { + PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, prop), RNA_struct_identifier(&self->ptr) ); + return -1; + } + + /* pyrna_py_to_prop sets its own exceptions */ + return pyrna_py_to_prop(&self->ptr, prop, value); }