From a7c4009267afe756ff0fa1a3935ae13eee02b1e3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Mar 2009 12:09:30 +0000 Subject: Make RNA an Operator dir() work in py 2.5 - 3.0 removed epy docstrings from RNA python api, since Python can get this info from rna. (could be redone in python if getting doc's on RNA is needed) epy_doc_gen works again --- source/blender/python/intern/bpy_operator.c | 54 +++---- source/blender/python/intern/bpy_rna.c | 210 +++++----------------------- 2 files changed, 55 insertions(+), 209 deletions(-) (limited to 'source/blender/python/intern') diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 3947dc8ab1e..a05456cfe9b 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -116,7 +116,7 @@ static int pyop_func_compare( BPy_OperatorFunc * a, BPy_OperatorFunc * b ) } /* For some reason python3 needs these :/ */ -static PyObject *pyop_func_richcmp(BPy_StructRNA * a, BPy_StructRNA * b, int op) +static PyObject *pyop_func_richcmp(BPy_OperatorFunc * a, BPy_OperatorFunc * b, int op) { int cmp_result= -1; /* assume false */ if (BPy_OperatorFunc_Check(a) && BPy_OperatorFunc_Check(b)) { @@ -138,6 +138,11 @@ static PyObject *pyop_func_repr( BPy_OperatorFunc * self ) return PyUnicode_FromFormat( "[BPy_OperatorFunc \"%s\"]", self->name); } +static struct PyMethodDef pyop_base_methods[] = { + {"add", (PyCFunction)PYOP_wrap_add, METH_VARARGS, ""}, + {"remove", (PyCFunction)PYOP_wrap_remove, METH_VARARGS, ""}, + {NULL, NULL, 0, NULL} +}; //---------------getattr-------------------------------------------- static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname ) @@ -149,6 +154,20 @@ static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname ) if ((ot = WM_operatortype_find(name))) { ret= pyop_func_CreatePyObject(self->C, name); } + else if (strcmp(name, "__dict__")==0) { + ret = PyDict_New(); + + wmOperatorType *ot; + PyMethodDef *meth; + + for(ot= WM_operatortype_first(); ot; ot= ot->next) { + PyDict_SetItemString(ret, ot->idname, Py_None); + } + + for(meth=pyop_base_methods; meth->ml_name; meth++) { + PyDict_SetItemString(ret, meth->ml_name, Py_None); + } + } else if ((ret = PyObject_GenericGetAttr((PyObject *)self, pyname))) { /* do nothing, this accounts for methoddef's add and remove */ } @@ -156,7 +175,7 @@ static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname ) PyErr_Format( PyExc_AttributeError, "Operator \"%s\" not found", name); ret= NULL; } - + return ret; } @@ -256,37 +275,6 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje Py_RETURN_NONE; } -PyObject *pyop_base_dir(PyObject *self); - -static struct PyMethodDef pyop_base_methods[] = { - {"add", (PyCFunction)PYOP_wrap_add, METH_VARARGS, ""}, - {"remove", (PyCFunction)PYOP_wrap_remove, METH_VARARGS, ""}, - {"__dir__", (PyCFunction)pyop_base_dir, METH_NOARGS, ""}, - {NULL, NULL, 0, NULL} -}; - -PyObject *pyop_base_dir(PyObject *self) -{ - PyObject *ret = PyList_New(0); - PyObject *item; - wmOperatorType *ot; - PyMethodDef *meth; - - for(ot= WM_operatortype_first(); ot; ot= ot->next) { - item = PyUnicode_FromString( ot->idname ); - PyList_Append(ret, item); - Py_DECREF(item); - } - - for(meth=pyop_base_methods; meth->ml_name; meth++) { - item = PyUnicode_FromString( meth->ml_name ); - PyList_Append(ret, item); - Py_DECREF(item); - } - - return ret; -} - /*-----------------------BPy_OperatorBase method def------------------------------*/ PyTypeObject pyop_base_Type = { #if (PY_VERSION_HEX >= 0x02060000) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 340e0cc8cb7..11a95646554 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -172,8 +172,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) break; } case PROP_COLLECTION: - PyErr_SetString(PyExc_AttributeError, "RNA Anomaly: Collection of length 0?"); - ret = NULL; /*pyrna_prop_CreatePyObject(ptr, prop);*/ + ret = pyrna_prop_CreatePyObject(ptr, prop); break; default: PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type); @@ -550,7 +549,7 @@ static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, P if (keynum >= len){ PyErr_SetString(PyExc_AttributeError, "index out of range"); ret = -1; - } else { /* not an array*/ + } else { ret = pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value); } } @@ -566,138 +565,6 @@ static PyMappingMethods pyrna_prop_as_mapping = { ( objobjargproc ) pyrna_prop_assign_subscript, /* mp_ass_subscript */ }; - -PyObject *pyrna_struct_to_docstring(BPy_StructRNA *self) -{ - PyObject *ret; - PropertyRNA *prop; - - DynStr *dynstr; - const char *identifier; - const char *desc; - char *readonly; - char *result; - int len; - int i; /* general iter */ - - dynstr= BLI_dynstr_new(); - BLI_dynstr_appendf(dynstr, "RNA %s: %s\n", RNA_struct_identifier(&self->ptr), RNA_struct_ui_name(&self->ptr)); - - /* Add EPI ===='s */ - i = BLI_dynstr_get_len(dynstr); - while (--i) - BLI_dynstr_append(dynstr, "="); - - BLI_dynstr_append(dynstr, "\n"); - /* done */ - - { - PropertyRNA *iterprop; - CollectionPropertyIterator iter; - - iterprop= RNA_struct_iterator_property(&self->ptr); - RNA_property_collection_begin(&self->ptr, iterprop, &iter); - - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop = iter.ptr.data; - identifier = RNA_property_identifier(&iter.ptr, prop); - desc = RNA_property_ui_description(&iter.ptr, prop); - - readonly = (RNA_property_editable(&self->ptr, prop)) ? "" : " *readonly*"; - len = RNA_property_array_length(&iter.ptr, prop); - - switch(RNA_property_type(&iter.ptr, prop)) { - case PROP_BOOLEAN: - { - BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly); - - if (len==0) BLI_dynstr_appendf(dynstr, "@type %s: bool\n", identifier); - else BLI_dynstr_appendf(dynstr, "@type %s: bool[%d]\n", identifier, len); - break; - } - case PROP_INT: - { - int hardmin, hardmax; - RNA_property_int_range(&iter.ptr, prop, &hardmin, &hardmax); - - BLI_dynstr_appendf(dynstr, "@ivar %s: %s in (%d, %d)%s\n", identifier, desc, hardmin, hardmax, readonly); - - if (len==0) BLI_dynstr_appendf(dynstr, "@type %s: int\n", identifier); - else BLI_dynstr_appendf(dynstr, "@type %s: int[%d]\n", identifier, len); - break; - } - case PROP_FLOAT: - { - float hardmin, hardmax; - RNA_property_float_range(&iter.ptr, prop, &hardmin, &hardmax); - - BLI_dynstr_appendf(dynstr, "@ivar %s: %s in (", identifier, desc); - - if (hardmin < -MAXFLOAT_DOC)BLI_dynstr_append(dynstr, "-inf, "); - else BLI_dynstr_appendf(dynstr, "%.3f, ", hardmin); - - if (hardmax > MAXFLOAT_DOC)BLI_dynstr_append(dynstr, "inf"); - else BLI_dynstr_appendf(dynstr, "%.3f", hardmax); - - BLI_dynstr_appendf(dynstr, ")%s\n", readonly); - - - if (len==0) BLI_dynstr_appendf(dynstr, "@type %s: float\n", identifier); - else BLI_dynstr_appendf(dynstr, "@type %s: float[%d]\n", identifier, len); - break; - } - case PROP_STRING: - { - int maxlen = RNA_property_string_maxlength(&iter.ptr, prop); - - BLI_dynstr_appendf(dynstr, "@ivar %s: %s (%d maximum length)%s\n", identifier, desc, maxlen, readonly); - BLI_dynstr_appendf(dynstr, "@type %s: string\n", identifier); - break; - } - case PROP_ENUM: - { - char *enum_str= pyrna_enum_as_string(&iter.ptr, prop); - BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly); - BLI_dynstr_appendf(dynstr, "@type %s: enum in [%s]\n", identifier, enum_str); - MEM_freeN(enum_str); - break; - } - case PROP_POINTER: - { - BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly); - - // TODO - why does this crash sometimes - // PointerRNA newptr; - // newptr= RNA_property_pointer_get(&iter.ptr, prop); - - // Use this instead, its not that useful - BLI_dynstr_appendf(dynstr, "@type %s: PyRNA %s\n", identifier, RNA_struct_identifier(&iter.ptr)); - break; - } - case PROP_COLLECTION: - BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly); - BLI_dynstr_appendf(dynstr, "@type %s: PyRNA Collection\n", identifier); - break; - default: - BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly); - BLI_dynstr_appendf(dynstr, "@type %s: \n", identifier); - break; - } - } - - RNA_property_collection_end(&iter); - } - - result= BLI_dynstr_get_cstring(dynstr); - BLI_dynstr_free(dynstr); - - ret = PyUnicode_FromString(result); - MEM_freeN(result); - - return ret; -} - - //---------------getattr-------------------------------------------- static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) { @@ -712,18 +579,37 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) if (ret) return ret; else PyErr_Clear(); /* done with subtypes */ + + prop = RNA_struct_find_property(&self->ptr, name); - if ( strcmp( name, "__doc__" ) == 0 ) { - ret = pyrna_struct_to_docstring(self); - } else { - prop = RNA_struct_find_property(&self->ptr, name); - - if (prop==NULL) { - PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name); - ret = NULL; - } else { - ret = pyrna_prop_to_py(&self->ptr, prop); + if (prop) { + ret = pyrna_prop_to_py(&self->ptr, prop); + } + else if (strcmp(name, "__dict__")==0) { /* Not quite correct, adding this so dir() gives good feedback */ + PropertyRNA *prop, *iterprop, *nameprop; + CollectionPropertyIterator iter; + char name[256], *nameptr; + + iterprop= RNA_struct_iterator_property(&self->ptr); + RNA_property_collection_begin(&self->ptr, iterprop, &iter); + + ret = PyDict_New(); + for(; iter.valid; RNA_property_collection_next(&iter)) { + nameprop= RNA_struct_name_property(&iter.ptr); + if(iter.ptr.data && nameprop) { + nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name)); + PyDict_SetItemString(ret, nameptr, Py_None); + + if ((char *)&name != nameptr) + MEM_freeN(nameptr); + } } + + RNA_property_collection_end(&iter); + } + else { + PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name); + ret = NULL; } return ret; @@ -749,32 +635,6 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje return pyrna_py_to_prop(&self->ptr, prop, value); } -static PyObject *pyrna_struct_dir( BPy_StructRNA * self ) -{ - PyObject *ret = PyList_New(0); - PyObject *item; - PropertyRNA *prop; - PropertyRNA *iterprop; - CollectionPropertyIterator iter; - - iterprop= RNA_struct_iterator_property(&self->ptr); - RNA_property_collection_begin(&self->ptr, iterprop, &iter); - - - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop = iter.ptr.data; - item = PyUnicode_FromString( RNA_property_identifier(&iter.ptr, prop) ); - PyList_Append(ret, item); - Py_DECREF(item); - } - - RNA_property_collection_end(&iter); - - return ret; -} - - - PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) { PyObject *ret; @@ -913,10 +773,10 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) return NULL; } -static struct PyMethodDef pyrna_struct_methods[] = { +/*static struct PyMethodDef pyrna_struct_methods[] = { {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, ""}, {NULL, NULL, 0, NULL} -}; +};*/ static struct PyMethodDef pyrna_prop_methods[] = { {"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, ""}, @@ -1023,7 +883,7 @@ PyTypeObject pyrna_struct_Type = { NULL, /* iternextfunc tp_iternext; */ /*** Attribute descriptor and subclassing stuff ***/ - pyrna_struct_methods, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMethodDef *tp_methods; */ NULL, /* struct PyMemberDef *tp_members; */ NULL, /* struct PyGetSetDef *tp_getset; */ NULL, /* struct _typeobject *tp_base; */ @@ -1164,8 +1024,6 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop ) pyrna->ptr = *ptr; pyrna->prop = prop; - - /* TODO - iterator? */ return ( PyObject * ) pyrna; } -- cgit v1.2.3