diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-06-05 16:48:58 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-06-05 16:48:58 +0400 |
commit | 52d8e64b857530c85efb6e1c38b4b4fd40d9c345 (patch) | |
tree | 41083ff76cc35ffd34cbd13fce5c163f754033f2 /source/blender/python/intern | |
parent | 13376a903b6167f26c04e14bad344374469fef25 (diff) |
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
Diffstat (limited to 'source/blender/python/intern')
-rw-r--r-- | source/blender/python/intern/bpy_operator.c | 69 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_operator.h | 3 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_operator_wrap.c | 2 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 96 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.h | 1 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_ui.c | 4 |
6 files changed, 99 insertions, 76 deletions
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index b03540fb765..004cf2fb7c7 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -41,73 +41,6 @@ extern ListBase global_ops; /* evil, temp use */ - - -/* This function is only used by operators right now - * Its used for taking keyword args and filling in property values */ -int PYOP_props_from_dict(PointerRNA *ptr, PyObject *kw) -{ - int error_val = 0; - int totkw; - const char *arg_name= NULL; - PyObject *item; - - PropertyRNA *prop, *iterprop; - CollectionPropertyIterator iter; - - iterprop= RNA_struct_iterator_property(ptr->type); - RNA_property_collection_begin(ptr, iterprop, &iter); - - totkw = kw ? PyDict_Size(kw):0; - - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop= iter.ptr.data; - - arg_name= RNA_property_identifier(prop); - - if (strcmp(arg_name, "rna_type")==0) continue; - - if (kw==NULL) { - PyErr_Format( PyExc_AttributeError, "no args, expected \"%s\"", arg_name ? arg_name : "<UNKNOWN>"); - error_val= -1; - break; - } - - item= PyDict_GetItemString(kw, arg_name); - - if (item == NULL) { - PyErr_Format( PyExc_AttributeError, "argument \"%s\" missing", arg_name ? arg_name : "<UNKNOWN>"); - error_val = -1; /* pyrna_py_to_prop sets the error */ - break; - } - - if (pyrna_py_to_prop(ptr, prop, NULL, item)) { - error_val= -1; - break; - } - - totkw--; - } - - RNA_property_collection_end(&iter); - - if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */ - PyObject *key, *value; - Py_ssize_t pos = 0; - - while (PyDict_Next(kw, &pos, &key, &value)) { - arg_name= _PyUnicode_AsString(key); - if (RNA_struct_find_property(ptr, arg_name) == NULL) break; - arg_name= NULL; - } - - PyErr_Format( PyExc_AttributeError, "argument \"%s\" unrecognized", arg_name ? arg_name : "<UNKNOWN>"); - error_val = -1; - } - - return error_val; -} - static PyObject *pyop_base_dir(PyObject *self); static PyObject *pyop_base_rna(PyObject *self, PyObject *pyname); static struct PyMethodDef pyop_base_methods[] = { @@ -148,7 +81,7 @@ static PyObject *pyop_base_call( PyObject * self, PyObject * args, PyObject * k WM_operator_properties_create(&ptr, opname); - error_val= PYOP_props_from_dict(&ptr, kw); + error_val= pyrna_pydict_to_props(&ptr, kw, "Converting py args to operator properties: "); if (error_val==0) { ReportList reports; diff --git a/source/blender/python/intern/bpy_operator.h b/source/blender/python/intern/bpy_operator.h index c4741f936bf..46ea144fd4d 100644 --- a/source/blender/python/intern/bpy_operator.h +++ b/source/blender/python/intern/bpy_operator.h @@ -42,7 +42,4 @@ typedef struct { PyObject *BPY_operator_module(void); -/* fill in properties from a python dict */ -int PYOP_props_from_dict(PointerRNA *ptr, PyObject *kw); - #endif diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 43d62b3005f..bf92db832af 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -272,7 +272,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve * thrown away anyway * * If we ever want to do this and use the props again, - * it can be done with - PYOP_props_from_dict(op->ptr, kw) + * it can be done with - pyrna_pydict_to_props(op->ptr, kw, "") */ Py_DECREF(ret); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index c1778faa1cd..d9a0d9408c7 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -204,6 +204,71 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) return ret; } +/* This function is only used by operators right now + * Its used for taking keyword args and filling in property values */ +int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefix) +{ + int error_val = 0; + int totkw; + const char *arg_name= NULL; + PyObject *item; + + PropertyRNA *prop, *iterprop; + CollectionPropertyIterator iter; + + iterprop= RNA_struct_iterator_property(ptr->type); + RNA_property_collection_begin(ptr, iterprop, &iter); + + totkw = kw ? PyDict_Size(kw):0; + + for(; iter.valid; RNA_property_collection_next(&iter)) { + prop= iter.ptr.data; + + arg_name= RNA_property_identifier(prop); + + if (strcmp(arg_name, "rna_type")==0) continue; + + if (kw==NULL) { + PyErr_Format( PyExc_AttributeError, "%s: no keywords, expected \"%s\"", error_prefix, arg_name ? arg_name : "<UNKNOWN>"); + error_val= -1; + break; + } + + item= PyDict_GetItemString(kw, arg_name); + + if (item == NULL) { + PyErr_Format( PyExc_AttributeError, "%s: keyword \"%s\" missing", error_prefix, arg_name ? arg_name : "<UNKNOWN>"); + error_val = -1; /* pyrna_py_to_prop sets the error */ + break; + } + + if (pyrna_py_to_prop(ptr, prop, NULL, item)) { + error_val= -1; + break; + } + + totkw--; + } + + RNA_property_collection_end(&iter); + + if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */ + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next(kw, &pos, &key, &value)) { + arg_name= _PyUnicode_AsString(key); + if (RNA_struct_find_property(ptr, arg_name) == NULL) break; + arg_name= NULL; + } + + PyErr_Format( PyExc_AttributeError, "%s: keyword \"%s\" unrecognized", error_prefix, arg_name ? arg_name : "<UNKNOWN>"); + error_val = -1; + } + + return error_val; +} + static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw); PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) @@ -447,9 +512,36 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v break; } case PROP_COLLECTION: - PyErr_SetString(PyExc_AttributeError, "cant convert collections yet"); - return -1; + { + int seq_len, i; + PyObject *item; + PointerRNA itemptr; + + /* convert a sequence of dict's into a collection */ + if(!PySequence_Check(value)) { + PyErr_SetString(PyExc_TypeError, "expected a sequence of dicts for an RNA collection"); + return -1; + } + + seq_len = PySequence_Length(value); + for(i=0; i<seq_len; i++) { + item= PySequence_GetItem(value, i); + if(item==NULL || PyDict_Check(item)==0) { + PyErr_SetString(PyExc_TypeError, "expected a sequence of dicts for an RNA collection"); + Py_XDECREF(item); + return -1; + } + + RNA_property_collection_add(ptr, prop, &itemptr); + if(pyrna_pydict_to_props(&itemptr, item, "Converting a python list to an RNA collection")==-1) { + Py_DECREF(item); + return -1; + } + Py_DECREF(item); + } + break; + } default: PyErr_SetString(PyExc_AttributeError, "unknown property type (pyrna_py_to_prop)"); return -1; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index a97d450fb2f..a2a3015912b 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -69,6 +69,7 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop ); /* operators also need this to set args */ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value); +int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefix); PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop); /* functions for setting up new props - experemental */ diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c index bbfb04719d8..c15315ca350 100644 --- a/source/blender/python/intern/bpy_ui.c +++ b/source/blender/python/intern/bpy_ui.c @@ -78,7 +78,7 @@ static PyObject *Method_defButO( PyObject * self, PyObject * args ) /* Optional python doctionary used to set python properties, just like how keyword args are used */ if (py_keywords && PyDict_Size(py_keywords)) { - if (PYOP_props_from_dict(uiButGetOperatorPtrRNA(but), py_keywords) == -1) + if (pyrna_pydict_to_props(uiButGetOperatorPtrRNA(but), py_keywords, "") == -1) return NULL; } @@ -296,7 +296,7 @@ static PyObject *Method_registerKey( PyObject * self, PyObject * args ) /* Optional python doctionary used to set python properties, just like how keyword args are used */ if (py_keywords && PyDict_Size(py_keywords)) { - if (PYOP_props_from_dict(km->ptr, py_keywords) == -1) + if (pyrna_pydict_to_props(km->ptr, py_keywords, "Registering keybinding") == -1) return NULL; } |