[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30835] trunk/blender/source/blender: fix for running rna subclasses own __init__ functions.

Campbell Barton ideasman42 at gmail.com
Wed Jul 28 14:11:40 CEST 2010


Revision: 30835
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30835
Author:   campbellbarton
Date:     2010-07-28 14:11:40 +0200 (Wed, 28 Jul 2010)

Log Message:
-----------
fix for running rna subclasses own __init__ functions.
- exceptions in the __init__ functions were not being checked for and segfaulting
- avoid creating a new BPy_StructRNA instance per function call, use the existing one if the type matches.

Modified Paths:
--------------
    trunk/blender/source/blender/makesrna/intern/rna_wm.c
    trunk/blender/source/blender/python/intern/bpy_rna.c

Modified: trunk/blender/source/blender/makesrna/intern/rna_wm.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_wm.c	2010-07-28 12:03:50 UTC (rev 30834)
+++ trunk/blender/source/blender/makesrna/intern/rna_wm.c	2010-07-28 12:11:40 UTC (rev 30835)
@@ -980,7 +980,6 @@
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_string_funcs(prop, "rna_Operator_name_get", "rna_Operator_name_length", NULL);
 	RNA_def_property_ui_text(prop, "Name", "");
-	RNA_def_struct_name_property(srna, prop);
 
 	prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE);
 	RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -1001,6 +1000,7 @@
 	RNA_def_property_string_sdna(prop, NULL, "type->idname");
 	RNA_def_property_string_maxlength(prop, OP_MAX_TYPENAME); /* else it uses the pointer size! */
 	RNA_def_property_flag(prop, PROP_REGISTER);
+	RNA_def_struct_name_property(srna, prop);
 
 	prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_sdna(prop, NULL, "type->name");
@@ -1043,7 +1043,6 @@
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_string_funcs(prop, "rna_Operator_name_get", "rna_Operator_name_length", NULL);
 	RNA_def_property_ui_text(prop, "Name", "");
-	RNA_def_struct_name_property(srna, prop);
 
 	prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE);
 	RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -1056,6 +1055,7 @@
 	RNA_def_property_string_sdna(prop, NULL, "type->idname");
 	RNA_def_property_string_maxlength(prop, OP_MAX_TYPENAME); /* else it uses the pointer size! */
 	RNA_def_property_flag(prop, PROP_REGISTER);
+	RNA_def_struct_name_property(srna, prop);
 
 	prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_sdna(prop, NULL, "type->name");

Modified: trunk/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_rna.c	2010-07-28 12:03:50 UTC (rev 30834)
+++ trunk/blender/source/blender/python/intern/bpy_rna.c	2010-07-28 12:11:40 UTC (rev 30835)
@@ -3086,37 +3086,47 @@
  * 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))
+	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)
@@ -4570,10 +4580,13 @@
 	else {
 		args = PyTuple_New(1);
 		PyTuple_SET_ITEM(args, 0, py_srna);
-		py_class_instance = PyObject_Call(py_class, args, NULL);
+		py_class_instance= PyObject_Call(py_class, args, NULL);
 		Py_DECREF(args);
-
-		if(py_class_instance_store) {
+		
+		if(py_class_instance == NULL) {
+			err= -1; /* so the error is not overridden below */
+		}
+		else if(py_class_instance_store) {
 			*py_class_instance_store = py_class_instance;
 			Py_INCREF(py_class_instance);
 		}
@@ -4626,8 +4639,11 @@
 		}
 	}
 	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 */





More information about the Bf-blender-cvs mailing list