Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2008-11-30 06:52:07 +0300
committerCampbell Barton <ideasman42@gmail.com>2008-11-30 06:52:07 +0300
commit18f3e5d69f7959afaf41a55a5e18cc0a0a2a0972 (patch)
treeac14ae25262908d18df08bccbd093dee7560e0da /source/blender/python
parentbc99bbde21c7a941fc41b6b9426a61d41a3e99d1 (diff)
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.
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/intern/bpy_rna.c284
1 files changed, 188 insertions, 96 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);
- }
- 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);
+ if (!PySequence_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array.");
+ return -1;
}
- 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);
+
+ if ((int)PySequence_Length(value) != len) {
+ PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array.");
+ return -1;
}
- 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);
+ /* 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");
+
+ /* 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) {
+ MEM_freeN(param_arr);
+ PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence is not a boolean");
+ return -1;
+ }
+ }
+
+ for (i=0; i<len; i++) {
+ RNA_property_boolean_set_array(ptr, prop, i, param_arr[i]);
+ }
+
+ MEM_freeN(param_arr);
+ break;
}
- break;
- }
- case PROP_ENUM:
- {
- char *param = _PyUnicode_AsString(value);
+ case PROP_INT:
+ {
+ int *param_arr = MEM_mallocN(sizeof(int) * len, "pyrna int 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] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */
+ Py_DECREF(item);
+ }
+
+ if (PyErr_Occurred()) {
+ MEM_freeN(param_arr);
+ PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as an int");
+ return -1;
+ }
+
+ for (i=0; i<len; i++) {
+ RNA_property_int_set_array(ptr, prop, i, param_arr[i]);
+ }
+
+ MEM_freeN(param_arr);
+ break;
+ }
+ case PROP_FLOAT:
+ {
+ float *param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float 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] = (float)PyFloat_AsDouble(item); /* deal with any errors later */
+ Py_DECREF(item);
+ }
+
+ if (PyErr_Occurred()) {
+ MEM_freeN(param_arr);
+ PyErr_SetString(PyExc_AttributeError, "one or more of the values in the sequence could not be used as a float");
+ return -1;
+ }
+
+ for (i=0; i<len; i++) {
+ RNA_property_float_set_array(ptr, prop, i, param_arr[i]);
+ }
+
+ MEM_freeN(param_arr);
+ break;
+ }
+ }
+ } else {
+ /* Normal Property (not an array) */
- if (param==NULL) {
- PyErr_SetString(PyExc_TypeError, "expected a string type");
- ret = -1;
- } else {
- const EnumPropertyItem *item;
- int totitem, i, val;
+ /* see if we can coorce into a python type - PropertyType */
+ switch (type) {
+ case PROP_BOOLEAN:
+ {
+ int param = PyObject_IsTrue( value );
- RNA_property_enum_items(ptr, prop, &item, &totitem);
+ if( param < 0 ) {
+ PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
+ return -1;
+ } else {
+ RNA_property_boolean_set(ptr, prop, param);
+ }
+ break;
+ }
+ case PROP_INT:
+ {
+ int param = PyLong_AsSsize_t(value);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "expected an int type");
+ return -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");
+ return -1;
+ } else {
+ RNA_property_float_set(ptr, prop, param);
+ }
+ break;
+ }
+ case PROP_STRING:
+ {
+ char *param = _PyUnicode_AsString(value);
- for (i=0; i<totitem; i++) {
- if (strcmp(item[i].identifier, param)==0) {
- val = item[i].value;
- break;
- }
+ if (param==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string type");
+ return -1;
+ } else {
+ RNA_property_string_set(ptr, prop, param);
}
+ break;
+ }
+ case PROP_ENUM:
+ {
+ char *param = _PyUnicode_AsString(value);
- if (i<totitem) {
- RNA_property_enum_set(ptr, prop, val);
+ if (param==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string type");
+ return -1;
} else {
- PyErr_Format(PyExc_AttributeError, "enum \"%s\" not found", param);
- ret = -1;
+ const EnumPropertyItem *item;
+ int totitem, i, val;
+
+ RNA_property_enum_items(ptr, prop, &item, &totitem);
+
+ for (i=0; i<totitem; i++) {
+ if (strcmp(item[i].identifier, param)==0) {
+ val = item[i].value;
+ break;
+ }
+ }
+
+ if (i<totitem) {
+ RNA_property_enum_set(ptr, prop, val);
+ } else {
+ PyErr_Format(PyExc_AttributeError, "enum \"%s\" not found", param);
+ return -1;
+ }
}
+
+ break;
+ }
+ case PROP_POINTER:
+ {
+ PyErr_SetString(PyExc_AttributeError, "cant assign pointers yet");
+ return -1;
+ break;
+ }
+ case PROP_COLLECTION:
+ PyErr_SetString(PyExc_AttributeError, "cant assign to collections");
+ return -1;
+ break;
+ default:
+ PyErr_SetString(PyExc_AttributeError, "unknown property type (pyrna_py_to_prop)");
+ return -1;
+ break;
}
-
- break;
- }
- case PROP_POINTER:
- {
- PyErr_SetString(PyExc_AttributeError, "cant assign pointers yet");
- ret = -1;
- break;
- }
- case PROP_COLLECTION:
- PyErr_SetString(PyExc_AttributeError, "cant assign to collections");
- break;
- default:
- PyErr_SetString(PyExc_AttributeError, "unknown property type (pyrna_py_to_prop)");
- ret = -1;
- break;
}
- return ret;
+ return 0;
}
@@ -279,7 +366,7 @@ static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index,
{
int param = PyObject_IsTrue( value );
- if( param == -1 ) {
+ if( param < 0 ) {
PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
ret = -1;
} else {
@@ -394,6 +481,11 @@ static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, P
int keynum;
char *keyname = NULL;
+ if (!RNA_property_editable(&self->ptr, 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);
}