diff options
Diffstat (limited to 'source/blender/python/intern/bpy_rna.c')
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 488 |
1 files changed, 349 insertions, 139 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index fbb806f6436..07b237a40f8 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -35,6 +35,7 @@ #include "MEM_guardedalloc.h" #include "BKE_utildefines.h" +#include "BKE_idcode.h" #include "BKE_context.h" #include "BKE_global.h" /* evil G.* */ #include "BKE_report.h" @@ -62,11 +63,11 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_ /* bpyrna vector/euler/quat callbacks */ static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */ -/* not used yet but may want to use the subtype below */ +/* subtype not used much yet */ #define MATHUTILS_CB_SUBTYPE_EUL 0 #define MATHUTILS_CB_SUBTYPE_VEC 1 #define MATHUTILS_CB_SUBTYPE_QUAT 2 -#define MATHUTILS_CB_SUBTYPE_COLOR 0 +#define MATHUTILS_CB_SUBTYPE_COLOR 3 static int mathutils_rna_generic_check(BaseMathObject *bmo) { @@ -418,25 +419,50 @@ static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op) } /*----------------------repr--------------------------------------------*/ -static PyObject *pyrna_struct_repr( BPy_StructRNA *self ) +static PyObject *pyrna_struct_str( BPy_StructRNA *self ) { - PyObject *pyob; + PyObject *ret; char *name; /* print name if available */ name= RNA_struct_name_get_alloc(&self->ptr, NULL, FALSE); if(name) { - pyob= PyUnicode_FromFormat( "<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name); + ret= PyUnicode_FromFormat( "<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name); MEM_freeN(name); - return pyob; + return ret; } return PyUnicode_FromFormat( "<bpy_struct, %.200s at %p>", RNA_struct_identifier(self->ptr.type), self->ptr.data); } -static PyObject *pyrna_prop_repr( BPy_PropertyRNA *self ) +static PyObject *pyrna_struct_repr(BPy_StructRNA *self) { - PyObject *pyob; + ID *id= self->ptr.id.data; + if(id == NULL) + return pyrna_struct_str(self); /* fallback */ + + if(RNA_struct_is_ID(self->ptr.type)) { + return PyUnicode_FromFormat( "bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id->name+2); + } + else { + PyObject *ret; + char *path; + path= RNA_path_from_ID_to_struct(&self->ptr); + if(path) { + ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path); + MEM_freeN(path); + } + else { /* cant find, print something sane */ + ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_struct_identifier(self->ptr.type)); + } + + return ret; + } +} + +static PyObject *pyrna_prop_str( BPy_PropertyRNA *self ) +{ + PyObject *ret; PointerRNA ptr; char *name; const char *type_id= NULL; @@ -470,15 +496,36 @@ static PyObject *pyrna_prop_repr( BPy_PropertyRNA *self ) name= RNA_struct_name_get_alloc(&ptr, NULL, FALSE); if(name) { - pyob= PyUnicode_FromFormat( "<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name); + ret= PyUnicode_FromFormat( "<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name); MEM_freeN(name); - return pyob; + return ret; } } return PyUnicode_FromFormat( "<bpy_%.200s, %.200s.%.200s>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop)); } +static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) +{ + ID *id= self->ptr.id.data; + PyObject *ret; + char *path; + + if(id == NULL) + return pyrna_prop_str(self); /* fallback */ + + path= RNA_path_from_ID_to_property(&self->ptr, self->prop); + if(path) { + ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path); + MEM_freeN(path); + } + else { /* cant find, print something sane */ + ret= PyUnicode_FromFormat( "bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_property_identifier(self->prop)); + } + + return ret; +} + static long pyrna_struct_hash( BPy_StructRNA *self ) { return _Py_HashPointer(self->ptr.data); @@ -1203,10 +1250,11 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr)) { return pyrna_struct_CreatePyObject(&newptr); } - PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d could not be found", keynum); - return NULL; + else { /* fail's if ptr.data == NULL, valid for mesh.materials */ + Py_RETURN_NONE; + } } - PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range", keynum); + PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range, size %d", keynum, len); return NULL; } @@ -1616,12 +1664,12 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value) return -1; } - if(RNA_struct_idproperties_check(self->ptr.type)==0) { + if(RNA_struct_idprops_check(self->ptr.type)==0) { PyErr_SetString( PyExc_TypeError, "bpy_struct: this type doesnt support IDProperties"); return -1; } - group= RNA_struct_idproperties(&self->ptr, 0); + group= RNA_struct_idprops(&self->ptr, 0); if(!group) return 0; @@ -1674,7 +1722,7 @@ static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key ) IDProperty *group, *idprop; char *name= _PyUnicode_AsString(key); - if(RNA_struct_idproperties_check(self->ptr.type)==0) { + if(RNA_struct_idprops_check(self->ptr.type)==0) { PyErr_SetString( PyExc_TypeError, "this type doesn't support IDProperties"); return NULL; } @@ -1684,7 +1732,7 @@ static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key ) return NULL; } - group= RNA_struct_idproperties(&self->ptr, 0); + group= RNA_struct_idprops(&self->ptr, 0); if(group==NULL) { PyErr_Format( PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name); @@ -1703,7 +1751,7 @@ static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key ) static int pyrna_struct_ass_subscript( BPy_StructRNA *self, PyObject *key, PyObject *value ) { - IDProperty *group= RNA_struct_idproperties(&self->ptr, 1); + IDProperty *group= RNA_struct_idprops(&self->ptr, 1); if(group==NULL) { PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type"); @@ -1733,12 +1781,12 @@ static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self) { IDProperty *group; - if(RNA_struct_idproperties_check(self->ptr.type)==0) { + if(RNA_struct_idprops_check(self->ptr.type)==0) { PyErr_SetString( PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties"); return NULL; } - group= RNA_struct_idproperties(&self->ptr, 0); + group= RNA_struct_idprops(&self->ptr, 0); if(group==NULL) return PyList_New(0); @@ -1760,12 +1808,12 @@ static PyObject *pyrna_struct_items(BPy_PropertyRNA *self) { IDProperty *group; - if(RNA_struct_idproperties_check(self->ptr.type)==0) { + if(RNA_struct_idprops_check(self->ptr.type)==0) { PyErr_SetString( PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties"); return NULL; } - group= RNA_struct_idproperties(&self->ptr, 0); + group= RNA_struct_idprops(&self->ptr, 0); if(group==NULL) return PyList_New(0); @@ -1787,12 +1835,12 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self) { IDProperty *group; - if(RNA_struct_idproperties_check(self->ptr.type)==0) { + if(RNA_struct_idprops_check(self->ptr.type)==0) { PyErr_SetString( PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties"); return NULL; } - group= RNA_struct_idproperties(&self->ptr, 0); + group= RNA_struct_idprops(&self->ptr, 0); if(group==NULL) return PyList_New(0); @@ -2039,12 +2087,34 @@ static char pyrna_struct_is_property_set_doc[] = static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args) { + PropertyRNA *prop; char *name; + int ret; if (!PyArg_ParseTuple(args, "s:is_property_set", &name)) return NULL; - return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); + if((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) { + PyErr_Format(PyExc_TypeError, "%.200s.is_property_set(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name); + return NULL; + } + + /* double property lookup, could speed up */ + /* return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); */ + if(RNA_property_flag(prop) & PROP_IDPROPERTY) { + IDProperty *group= RNA_struct_idprops(&self->ptr, 0); + if(group) { + ret= IDP_GetPropertyFromGroup(group, name) ? 1:0; + } + else { + ret= 0; + } + } + else { + ret= 1; + } + + return PyBool_FromLong(ret); } static char pyrna_struct_is_property_hidden_doc[] = @@ -2059,15 +2129,16 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject * { PropertyRNA *prop; char *name; - int hidden; if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) return NULL; - - prop= RNA_struct_find_property(&self->ptr, name); - hidden= (prop)? (RNA_property_flag(prop) & PROP_HIDDEN): 1; - return PyBool_FromLong(hidden); + if((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) { + PyErr_Format(PyExc_TypeError, "%.200s.is_property_hidden(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name); + return NULL; + } + + return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN); } static char pyrna_struct_path_resolve_doc[] = @@ -2289,7 +2360,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname ) if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups /* annoying exception, maybe we need to have different types for this... */ - if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idproperties_check(self->ptr.type)) { + if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idprops_check(self->ptr.type)) { PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type"); ret = NULL; } @@ -2684,12 +2755,12 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args) return NULL; /* mostly copied from BPy_IDGroup_Map_GetItem */ - if(RNA_struct_idproperties_check(self->ptr.type)==0) { + if(RNA_struct_idprops_check(self->ptr.type)==0) { PyErr_SetString( PyExc_TypeError, "this type doesn't support IDProperties"); return NULL; } - group= RNA_struct_idproperties(&self->ptr, 0); + group= RNA_struct_idprops(&self->ptr, 0); if(group) { idprop= IDP_GetPropertyFromGroup(group, key); @@ -3060,8 +3131,6 @@ static struct PyMethodDef pyrna_prop_methods[] = { }; static struct PyMethodDef pyrna_prop_array_methods[] = { - {"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL}, - {"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; @@ -3086,37 +3155,47 @@ static struct PyMethodDef pyrna_prop_collection_methods[] = { * todo - also accept useful args */ static PyObject * pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - BPy_StructRNA *base = NULL; + BPy_StructRNA *base; if (!PyArg_ParseTuple(args, "O!:bpy_struct.__new__", &pyrna_struct_Type, &base)) return NULL; - - if (type == &pyrna_struct_Type) { - return pyrna_struct_CreatePyObject(&base->ptr); - } else { + + if (type == Py_TYPE(base)) { + Py_INCREF(base); + return (PyObject *)base; + } else if (PyType_IsSubtype(type, &pyrna_struct_Type)) { BPy_StructRNA *ret = (BPy_StructRNA *) type->tp_alloc(type, 0); ret->ptr = base->ptr; return (PyObject *)ret; } + else { + PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct.", type->tp_name); + return NULL; + } } /* only needed for subtyping, so a new class gets a valid BPy_StructRNA * todo - also accept useful args */ static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - BPy_PropertyRNA *base = NULL; + BPy_PropertyRNA *base; - if (!PyArg_ParseTuple(args, "O!:Base BPy_PropertyRNA", &pyrna_prop_Type, &base)) + if (!PyArg_ParseTuple(args, "O!:bpy_prop.__new__", &pyrna_prop_Type, &base)) return NULL; - if (ELEM3(type, &pyrna_prop_Type, &pyrna_prop_array_Type, &pyrna_prop_collection_Type)) { - return pyrna_prop_CreatePyObject(&base->ptr, base->prop); - } else { + if (type == Py_TYPE(base)) { + Py_INCREF(base); + return (PyObject *)base; + } else if (PyType_IsSubtype(type, &pyrna_prop_Type)) { BPy_PropertyRNA *ret = (BPy_PropertyRNA *) type->tp_alloc(type, 0); ret->ptr = base->ptr; ret->prop = base->prop; return (PyObject *)ret; } + else { + PyErr_Format(PyExc_TypeError, "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop.", type->tp_name); + return NULL; + } } PyObject *pyrna_param_to_py(PointerRNA *ptr, ParameterList *parms, PropertyRNA *prop, void *data) @@ -3520,7 +3599,7 @@ PyTypeObject pyrna_struct_Type = { ( hashfunc )pyrna_struct_hash, /* hashfunc tp_hash; */ NULL, /* ternaryfunc tp_call; */ - NULL, /* reprfunc tp_str; */ + (reprfunc) pyrna_struct_str, /* reprfunc tp_str; */ ( getattrofunc ) pyrna_struct_getattro, /* getattrofunc tp_getattro; */ ( setattrofunc ) pyrna_struct_setattro, /* setattrofunc tp_setattro; */ @@ -3587,7 +3666,7 @@ PyTypeObject pyrna_prop_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */ - ( reprfunc ) pyrna_prop_repr, /* tp_repr */ + (reprfunc) pyrna_prop_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -3599,7 +3678,7 @@ PyTypeObject pyrna_prop_Type = { ( hashfunc ) pyrna_prop_hash, /* hashfunc tp_hash; */ NULL, /* ternaryfunc tp_call; */ - NULL, /* reprfunc tp_str; */ + (reprfunc) pyrna_prop_str, /* reprfunc tp_str; */ /* will only use these if this is a subtype of a py class */ NULL, /* getattrofunc tp_getattro; */ @@ -3970,7 +4049,7 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna) - myClass = type(name='myClass', bases=(myBase,), dict={'__module__':'bpy.types'}) */ - /* Assume RNA_struct_py_type_get(srna) was alredy checked */ + /* Assume RNA_struct_py_type_get(srna) was already checked */ PyObject *py_base= pyrna_srna_PyBase(srna); const char *idname= RNA_struct_identifier(srna); @@ -4163,6 +4242,9 @@ static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA *self, PyObject *pynam } static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self); +static PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class); +static PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class); + static struct PyMethodDef pyrna_basetype_methods[] = { {"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""}, {"register", (PyCFunction)pyrna_basetype_register, METH_O, ""}, @@ -4232,18 +4314,18 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_pr } if(py_srna==NULL) { - PyErr_Format(PyExc_SystemError, "%.200s internal error, self of type '%.200s' had no bl_rna attribute, should never happen", error_prefix, Py_TYPE(self)->tp_name); + PyErr_Format(PyExc_SystemError, "%.200s, missing bl_rna attribute from '%.200s' instance (may not be registered)", error_prefix, Py_TYPE(self)->tp_name); return NULL; } if(!BPy_StructRNA_Check(py_srna)) { - PyErr_Format(PyExc_SystemError, "%.200s internal error, bl_rna was of type '%.200s', instead of %.200s instance", error_prefix, Py_TYPE(py_srna)->tp_name, pyrna_struct_Type.tp_name); + PyErr_Format(PyExc_SystemError, "%.200s, bl_rna attribute wrong type '%.200s' on '%.200s'' instance", error_prefix, Py_TYPE(py_srna)->tp_name, Py_TYPE(self)->tp_name); Py_DECREF(py_srna); return NULL; } if(py_srna->ptr.type != &RNA_Struct) { - PyErr_Format(PyExc_SystemError, "%.200s internal error, bl_rna was not a RNA_Struct type of rna struct", error_prefix); + PyErr_Format(PyExc_SystemError, "%.200s, bl_rna attribute not a RNA_Struct, on '%.200s'' instance", error_prefix, Py_TYPE(self)->tp_name); Py_DECREF(py_srna); return NULL; } @@ -4291,7 +4373,6 @@ static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key if(*_PyUnicode_AsString(key)=='_') { PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: %.200s could not register because the property starts with an '_'\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); - Py_DECREF(dummy_args); return -1; } pyfunc = PyCapsule_GetPointer(py_func_ptr, NULL); @@ -4312,8 +4393,6 @@ static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key // PyLineSpit(); PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); - - Py_DECREF(dummy_args); return -1; } } @@ -4330,7 +4409,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key return 0; } -int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) +static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) { PyObject *item, *key; PyObject *order; @@ -4340,12 +4419,10 @@ int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) dummy_args = PyTuple_New(0); - order= PyDict_GetItemString(class_dict, "order"); - - if(order==NULL) - PyErr_Clear(); - - if(order && PyList_Check(order)) { + if( !PyDict_CheckExact(class_dict) && + (order= PyDict_GetItemString(class_dict, "order")) && + PyList_CheckExact(order) + ) { for(pos= 0; pos<PyList_GET_SIZE(order); pos++) { key= PyList_GET_ITEM(order, pos); item= PyDict_GetItem(class_dict, key); @@ -4368,6 +4445,49 @@ int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) return 0; } +static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject *py_class) +{ + const int len= PyTuple_GET_SIZE(py_class->tp_bases); + int i, ret; + + /* first scan base classes for registerable properties */ + for(i=0; i<len; i++) { + PyTypeObject *py_superclass= (PyTypeObject *)PyTuple_GET_ITEM(py_class->tp_bases, i); + + /* the rules for using these base classes are not clear, + * 'object' is ofcourse not worth looking into and + * existing subclasses of RNA would cause a lot more dictionary + * looping then is needed (SomeOperator would scan Operator.__dict__) + * which is harmless but not at all useful. + * + * So only scan base classes which are not subclasses if blender types. + * This best fits having 'mix-in' classes for operators and render engines. + * */ + if( py_superclass != &PyBaseObject_Type && + !PyObject_IsSubclass((PyObject *)py_superclass, (PyObject *)&pyrna_struct_Type) + ) { + ret= pyrna_deferred_register_class_recursive(srna, py_superclass); + + if(ret != 0) { + return ret; + } + } + } + + /* not register out own properties */ + return pyrna_deferred_register_props(srna, py_class->tp_dict); /* getattr(..., "__dict__") returns a proxy */ +} + +int pyrna_deferred_register_class(StructRNA *srna, PyObject *py_class) +{ + /* Panels and Menus dont need this + * save some time and skip the checks here */ + if(!RNA_struct_idprops_register_check(srna)) + return 0; + + return pyrna_deferred_register_class_recursive(srna, (PyTypeObject *)py_class); +} + /*-------------------- Type Registration ------------------------*/ static int rna_function_arg_count(FunctionRNA *func) @@ -4375,7 +4495,7 @@ static int rna_function_arg_count(FunctionRNA *func) const ListBase *lb= RNA_function_defined_parameters(func); PropertyRNA *parm; Link *link; - int count= 1; + int count= (RNA_function_flag(func) & FUNC_NO_SELF) ? 0 : 1; for(link=lb->first; link; link=link->next) { parm= (PropertyRNA*)link; @@ -4396,7 +4516,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun const char *class_type= RNA_struct_identifier(srna); PyObject *py_class= (PyObject*)py_data; PyObject *base_class= RNA_struct_py_type_get(srna); - PyObject *item, *fitem; + PyObject *item; PyObject *py_arg_count; int i, flag, arg_count, func_arg_count; const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; // __name__ @@ -4433,25 +4553,33 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun PyErr_Clear(); } else { - Py_DECREF(item); /* no need to keep a ref, the class owns it */ - - if (PyMethod_Check(item)) - fitem= PyMethod_Function(item); /* py 2.x */ - else - fitem= item; /* py 3.x */ - - if (PyFunction_Check(fitem)==0) { - PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a function", class_type, py_class_name, RNA_function_identifier(func)); - return -1; + Py_DECREF(item); /* no need to keep a ref, the class owns it (technically we should keep a ref but...) */ + if(flag & FUNC_NO_SELF) { + if (PyMethod_Check(item)==0) { + PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a method, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name); + return -1; + } + item= ((PyMethodObject *)item)->im_func; + } + else { + if (PyFunction_Check(item)==0) { + PyErr_Format( PyExc_TypeError, "expected %.200s, %.200s class \"%.200s\" attribute to be a function, not a %.200s", class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name); + return -1; + } } func_arg_count= rna_function_arg_count(func); if (func_arg_count >= 0) { /* -1 if we dont care*/ - py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(fitem), "co_argcount"); + py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(item), "co_argcount"); arg_count = PyLong_AsSsize_t(py_arg_count); Py_DECREF(py_arg_count); + /* note, the number of args we check for and the number of args we give to + * @classmethods are different (quirk of python), this is why rna_function_arg_count() doesn't return the value -1*/ + if(flag & FUNC_NO_SELF) + func_arg_count++; + if (arg_count != func_arg_count) { PyErr_Format( PyExc_AttributeError, "expected %.200s, %.200s class \"%.200s\" function to have %d args, found %d", class_type, py_class_name, RNA_function_identifier(func), func_arg_count, arg_count); return -1; @@ -4524,6 +4652,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par ParameterIterator iter; PointerRNA funcptr; int err= 0, i, flag, ret_len=0; + int is_static = RNA_function_flag(func) & FUNC_NO_SELF; PropertyRNA *pret_single= NULL; void *retdata_single= NULL; @@ -4531,52 +4660,64 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par PyGILState_STATE gilstate; bContext *C= BPy_GetContext(); // XXX - NEEDS FIXING, QUITE BAD. + + py_class= RNA_struct_py_type_get(ptr->type); + + /* rare case. can happen when registering subclasses */ + if(py_class==NULL) { + fprintf(stderr, "bpy_class_call(): unable to get python class for rna struct '%.200s'\n", RNA_struct_identifier(ptr->type)); + return -1; + } + bpy_context_set(C, &gilstate); - py_class= RNA_struct_py_type_get(ptr->type); + if (!is_static) { + /* exception, operators store their PyObjects for re-use */ + if(ptr->data) { + if(RNA_struct_is_a(ptr->type, &RNA_Operator)) { + wmOperator *op= ptr->data; + if(op->py_instance) { + py_class_instance= op->py_instance; + Py_INCREF(py_class_instance); + } + else { + /* store the instance here once its created */ + py_class_instance_store= &op->py_instance; + } + } + } + /* end exception */ - /* exception, operators store their PyObjects for re-use */ - if(ptr->data) { - if(RNA_struct_is_a(ptr->type, &RNA_Operator)) { - wmOperator *op= ptr->data; - if(op->py_instance) { - py_class_instance= op->py_instance; - Py_INCREF(py_class_instance); + if(py_class_instance==NULL) + py_srna= pyrna_struct_CreatePyObject(ptr); + + if(py_class_instance) { + /* special case, instance is cached */ + } + else if(py_srna == NULL) { + py_class_instance = NULL; + } + else if(py_srna == Py_None) { /* probably wont ever happen but possible */ + Py_DECREF(py_srna); + py_class_instance = NULL; + } + else { + args = PyTuple_New(1); + PyTuple_SET_ITEM(args, 0, py_srna); + py_class_instance= PyObject_Call(py_class, args, NULL); + Py_DECREF(args); + + if(py_class_instance == NULL) { + err= -1; /* so the error is not overridden below */ } - else { - /* store the instance here once its created */ - py_class_instance_store= &op->py_instance; + else if(py_class_instance_store) { + *py_class_instance_store = py_class_instance; + Py_INCREF(py_class_instance); } } } - /* end exception */ - - if(py_class_instance==NULL) - py_srna= pyrna_struct_CreatePyObject(ptr); - - if(py_class_instance) { - /* special case, instance is cached */ - } - else if(py_srna == NULL) { - py_class_instance = NULL; - } - else if(py_srna == Py_None) { /* probably wont ever happen but possible */ - Py_DECREF(py_srna); - py_class_instance = NULL; - } - else { - args = PyTuple_New(1); - PyTuple_SET_ITEM(args, 0, py_srna); - py_class_instance = PyObject_Call(py_class, args, NULL); - Py_DECREF(args); - - if(py_class_instance_store) { - *py_class_instance_store = py_class_instance; - Py_INCREF(py_class_instance); - } - } - if (py_class_instance) { /* Initializing the class worked, now run its invoke function */ + if (is_static || py_class_instance) { /* Initializing the class worked, now run its invoke function */ PyObject *item= PyObject_GetAttrString(py_class, RNA_function_identifier(func)); // flag= RNA_function_flag(func); @@ -4584,12 +4725,19 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par RNA_pointer_create(NULL, &RNA_Function, func, &funcptr); args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */ - PyTuple_SET_ITEM(args, 0, py_class_instance); + + if(is_static) { + i= 0; + } + else { + PyTuple_SET_ITEM(args, 0, py_class_instance); + i= 1; + } RNA_parameter_list_begin(parms, &iter); /* parse function parameters */ - for (i= 1; iter.valid; RNA_parameter_list_next(&iter)) { + for (; iter.valid; RNA_parameter_list_next(&iter)) { parm= iter.parm; flag= RNA_property_flag(parm); @@ -4623,8 +4771,11 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par } } else { - PyErr_Format(PyExc_RuntimeError, "could not create instance of %.200s to call callback function %.200s.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func)); - err= -1; + /* the error may be alredy set if the class instance couldnt be created */ + if(err != -1) { + PyErr_Format(PyExc_RuntimeError, "could not create instance of %.200s to call callback function %.200s.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func)); + err= -1; + } } if (ret == NULL) { /* covers py_class_instance failing too */ @@ -4717,7 +4868,16 @@ void pyrna_alloc_types(void) prop = RNA_struct_find_property(&ptr, "structs"); RNA_PROP_BEGIN(&ptr, itemptr, prop) { - Py_DECREF(pyrna_struct_Subtype(&itemptr)); + PyObject *item= pyrna_struct_Subtype(&itemptr); + if(item == NULL) { + if(PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } + } + else { + Py_DECREF(item); + } } RNA_PROP_END; @@ -4760,15 +4920,14 @@ void pyrna_free_types(void) * - Should still be fixed - Campbell * */ -PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class) +static PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class) { bContext *C= NULL; ReportList reports; StructRegisterFunc reg; StructRNA *srna; StructRNA *srna_new; - PyObject *item; - const char *identifier= ""; + const char *identifier; if(PyDict_GetItemString(((PyTypeObject*)py_class)->tp_dict, "bl_rna")) { PyErr_SetString(PyExc_AttributeError, "bpy.types.register(...): already registered as a subclass."); @@ -4780,11 +4939,19 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class) if(srna==NULL) return NULL; + /* fails in cases, cant use this check but would like to :| */ + /* + if(RNA_struct_py_type_get(srna)) { + PyErr_Format(PyExc_ValueError, "bpy.types.register(...): %.200s's parent class %.200s is alredy registered, this is not allowed.", ((PyTypeObject*)py_class)->tp_name, RNA_struct_identifier(srna)); + return NULL; + } + */ + /* check that we have a register callback for this type */ reg= RNA_struct_register(srna); if(!reg) { - PyErr_SetString(PyExc_ValueError, "bpy.types.register(...): expected a Type subclassed from a registerable rna type (no register supported)."); + PyErr_Format(PyExc_ValueError, "bpy.types.register(...): expected a subclass of a registerable rna type (%.200s does not support registration).", RNA_struct_identifier(srna)); return NULL; } @@ -4794,12 +4961,7 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class) /* call the register callback with reports & identifier */ BKE_reports_init(&reports, RPT_STORE); - item= PyObject_GetAttrString(py_class, "__name__"); - - if(item) { - identifier= _PyUnicode_AsString(item); - Py_DECREF(item); /* no need to keep a ref, the class owns it */ - } + identifier= ((PyTypeObject*)py_class)->tp_name; srna_new= reg(C, &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free); @@ -4823,27 +4985,47 @@ PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class) * * item= PyObject_GetAttrString(py_class, "__dict__"); */ - item= ((PyTypeObject*)py_class)->tp_dict; - if(item) { - if(pyrna_deferred_register_props(srna_new, item)!=0) { - return NULL; - } - } - else { - PyErr_Clear(); - } + if(pyrna_deferred_register_class(srna_new, py_class)!=0) + return NULL; Py_RETURN_NONE; } -PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class) + +static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props, StructRNA *srna, const char **prop_identifier) +{ + PointerRNA tptr; + PropertyRNA *iterprop; + RNA_pointer_create(NULL, &RNA_Struct, srna_props, &tptr); + + iterprop= RNA_struct_find_property(&tptr, "properties"); + + RNA_PROP_BEGIN(&tptr, itemptr, iterprop) { + PropertyRNA *prop= itemptr.data; + if(RNA_property_type(prop) == PROP_POINTER) { + if (strcmp(RNA_property_identifier(prop), "rna_type") == 0) { + /* pass */ + } + else if(RNA_property_pointer_type(&tptr, prop) == srna) { + *prop_identifier= RNA_property_identifier(prop); + return 1; + } + } + } + RNA_PROP_END; + + return 0; +} + +static PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class) { bContext *C= NULL; StructUnregisterFunc unreg; StructRNA *srna; /*if(PyDict_GetItemString(((PyTypeObject*)py_class)->tp_dict, "bl_rna")==NULL) { - PyErr_SetString(PyExc_ValueError, "bpy.types.unregister(): not a registered as a subclass."); + PWM_cursor_wait(0); +yErr_SetString(PyExc_ValueError, "bpy.types.unregister(): not a registered as a subclass."); return NULL; }*/ @@ -4859,6 +5041,34 @@ PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class) return NULL; } + /* should happen all the time but very slow */ + if(G.f & G_DEBUG) { + /* remove all properties using this class */ + StructRNA *srna_iter; + PointerRNA ptr_rna; + PropertyRNA *prop_rna; + const char *prop_identifier= NULL; + + RNA_blender_rna_pointer_create(&ptr_rna); + prop_rna = RNA_struct_find_property(&ptr_rna, "structs"); + + + + /* loop over all structs */ + RNA_PROP_BEGIN(&ptr_rna, itemptr, prop_rna) { + srna_iter = itemptr.data; + if(pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) { + break; + } + } + RNA_PROP_END; + + if(prop_identifier) { + PyErr_Format(PyExc_SystemError, "bpy.types.unregister(...): Cant unregister %s because %s.%s pointer property is using this.", RNA_struct_identifier(srna), RNA_struct_identifier(srna_iter), prop_identifier); + return NULL; + } + } + /* get the context, so register callback can do necessary refreshes */ C= BPy_GetContext(); |