diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-08-24 06:12:09 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-08-24 06:12:09 +0400 |
commit | 48e34b995686d50177932660ec422528eb4a6da8 (patch) | |
tree | e6192cb361eb0e5876d8c3804f83a1015b481f01 /source/blender/python | |
parent | 27edda14dd92c28ed389a5b3691429f31390c51f (diff) |
- pythons 'del somevalue.attr' could crash when used with the rna api (reported by Luca)
eg:
bpy.context.StringProperty(attr='myprop'); del bpy.context.myprop
- made rna StringProperty/PointerProperty & similar into class methods.
- file selector hide option was inverted
Diffstat (limited to 'source/blender/python')
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 72639ba221c..43f11d25e55 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2478,6 +2478,11 @@ static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObjec char *name = _PyUnicode_AsString(pyname); PropertyRNA *prop= NULL; + if(value == NULL) { + PyErr_SetString(PyExc_AttributeError, "bpy_struct: del not supported"); + return -1; + } + if (name[0] != '_' && (prop= RNA_struct_find_property(&self->ptr, name))) { if (!RNA_property_editable_flag(&self->ptr, prop)) { PyErr_Format( PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) ); @@ -2577,6 +2582,11 @@ static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyna PropertyRNA *prop; PointerRNA r_ptr; + if(value == NULL) { + PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported"); + return -1; + } + if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { if ((prop = RNA_struct_find_property(&r_ptr, name))) { /* pyrna_py_to_prop sets its own exceptions */ @@ -3134,6 +3144,20 @@ static struct PyMethodDef pyrna_struct_methods[] = { {"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL}, {"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL}, + /* class methods, only valid for subclasses */ + {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_BoolProperty_doc}, + {"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_BoolVectorProperty_doc}, + {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_IntProperty_doc}, + {"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_IntVectorProperty_doc}, + {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_FloatProperty_doc}, + {"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_FloatVectorProperty_doc}, + {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_StringProperty_doc}, + {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_EnumProperty_doc}, + {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_PointerProperty_doc}, + {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_CollectionProperty_doc}, + + {"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS|METH_CLASS, BPy_RemoveProperty_doc}, + {NULL, NULL, 0, NULL} }; @@ -3908,28 +3932,11 @@ PyTypeObject pyrna_prop_collection_Type = { NULL }; -static struct PyMethodDef pyrna_struct_subtype_methods[] = { - {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc}, - {"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolVectorProperty_doc}, - {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntProperty_doc}, - {"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntVectorProperty_doc}, - {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatProperty_doc}, - {"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatVectorProperty_doc}, - {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, BPy_StringProperty_doc}, - {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, BPy_EnumProperty_doc}, - {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, BPy_PointerProperty_doc}, - {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, BPy_CollectionProperty_doc}, - - {"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, BPy_RemoveProperty_doc}, - -// {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""}, - {NULL, NULL, 0, NULL} -}; - static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) { PointerRNA ptr; PyObject *item; + PyObject *newclass_dict= ((PyTypeObject *)newclass)->tp_dict; Py_INCREF(newclass); @@ -3948,20 +3955,9 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) item = pyrna_struct_CreatePyObject(&ptr); //item = PyCapsule_New(srna, NULL, NULL); - PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "bl_rna", item); + PyDict_SetItemString(newclass_dict, "bl_rna", item); Py_DECREF(item); /* done with rna instance */ - - /* attach functions into the class - * so you can do... bpy.types.Scene.SomeFunction() - */ - { - PyMethodDef *ml; - - for(ml= pyrna_struct_subtype_methods; ml->ml_name; ml++){ - PyObject_SetAttrString(newclass, ml->ml_name, PyCFunction_New(ml, newclass)); - } - } } static PyObject* pyrna_srna_Subtype(StructRNA *srna); @@ -4048,14 +4044,19 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna) { PyObject *newclass = NULL; + /* stupid/simple case */ if (srna == NULL) { newclass= NULL; /* Nothing to do */ - } else if ((newclass= RNA_struct_py_type_get(srna))) { + } /* the class may have alredy been declared & allocated */ + else if ((newclass= RNA_struct_py_type_get(srna))) { Py_INCREF(newclass); - } else if ((newclass= pyrna_srna_ExternalType(srna))) { + } /* check if bpy_types.py module has the class defined in it */ + else if ((newclass= pyrna_srna_ExternalType(srna))) { pyrna_subtype_set_rna(newclass, srna); Py_INCREF(newclass); - } else { + } /* create a new class instance with the C api + * maintly for the purposing of matching the C/rna type hierarchy */ + else { /* subclass equivelents - class myClass(myBase): some='value' # or ... @@ -4066,12 +4067,14 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna) PyObject *py_base= pyrna_srna_PyBase(srna); const char *idname= RNA_struct_identifier(srna); - const char *descr= RNA_struct_ui_description(srna); - - if(!descr) descr= "(no docs)"; + + /* remove __doc__ for now */ + // const char *descr= RNA_struct_ui_description(srna); + // if(!descr) descr= "(no docs)"; + // "__doc__",descr /* always use O not N when calling, N causes refcount errors */ - newclass = PyObject_CallFunction( (PyObject*)&PyType_Type, "s(O){sssss()}", idname, py_base, "__module__","bpy.types", "__doc__",descr, "__slots__"); + newclass = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sss()}", idname, py_base, "__module__","bpy.types", "__slots__"); /* newclass will now have 2 ref's, ???, probably 1 is internal since decrefing here segfaults */ /* PyObSpit("new class ref", newclass); */ @@ -4080,7 +4083,8 @@ static PyObject* pyrna_srna_Subtype(StructRNA *srna) /* srna owns one, and the other is owned by the caller */ pyrna_subtype_set_rna(newclass, srna); - Py_DECREF(newclass); /* let srna own */ + // XXX, adding this back segfaults blender on load. + // Py_DECREF(newclass); /* let srna own */ } else { /* this should not happen */ |