[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22460] branches/blender2.5/blender/source /blender/python: RNA Types were storing an instance of themself for class introspection and docs but makes freeing the type complicated .

Campbell Barton ideasman42 at gmail.com
Sat Aug 15 07:05:23 CEST 2009


Revision: 22460
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22460
Author:   campbellbarton
Date:     2009-08-15 07:05:23 +0200 (Sat, 15 Aug 2009)

Log Message:
-----------
RNA Types were storing an instance of themself for class introspection and docs but makes freeing the type complicated.

now __rna__ is a PyCObject rather then a BPy_StructRNA instance, to get the rna from python use __get_rna() now.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/python/epy_doc_gen.py
    branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c

Modified: branches/blender2.5/blender/source/blender/python/epy_doc_gen.py
===================================================================
--- branches/blender2.5/blender/source/blender/python/epy_doc_gen.py	2009-08-15 00:40:44 UTC (rev 22459)
+++ branches/blender2.5/blender/source/blender/python/epy_doc_gen.py	2009-08-15 05:05:23 UTC (rev 22460)
@@ -313,9 +313,9 @@
 	structs = []
 	for rna_type_name in dir(bpy.types):
 		rna_type = getattr(bpy.types, rna_type_name)
-		if hasattr(rna_type, '__rna__'):
+		if hasattr(rna_type, '__get_rna'):
 			#if not rna_type_name.startswith('__'):
-			rna_struct = rna_type.__rna__
+			rna_struct = rna_type.__get_rna()
 			identifier = rna_struct.identifier
 			structs.append( (base_id(rna_struct), identifier, rna_struct) )	
 			

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2009-08-15 00:40:44 UTC (rev 22459)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2009-08-15 05:05:23 UTC (rev 22460)
@@ -132,6 +132,8 @@
 
 #endif
 
+static StructRNA *pyrna_struct_as_srna(PyObject *self);
+
 static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
 {
 	return (a->ptr.data==b->ptr.data) ? 0 : -1;
@@ -2259,7 +2261,7 @@
 
 static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
 {
-	PointerRNA ptr;
+	//PointerRNA ptr;
 	PyObject *item;
 	
 	Py_INCREF(newclass);
@@ -2273,18 +2275,42 @@
 
 	/* Not 100% needed but useful,
 	 * having an instance within a type looks wrong however this instance IS an rna type */
-	RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr);
-	item = pyrna_struct_CreatePyObject(&ptr);
+
+	/* cant use the real pytype because it makes a usercount deadlock */
+	//RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr);
+	//item = pyrna_struct_CreatePyObject(&ptr);
+
+	item = PyCObject_FromVoidPtr(srna, NULL);
 	PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", item);
 	Py_DECREF(item);
 	/* done with rna instance */
 }
 
+static StructRNA *srna_from_self(PyObject *self);
+PyObject *BPy_GetStructRNA(PyObject *self)
+{
+	StructRNA *srna= pyrna_struct_as_srna(self);
+	PointerRNA ptr;
+	PyObject *ret;
+
+	RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr);
+	ret= pyrna_struct_CreatePyObject(&ptr);
+
+	if(ret) {
+		return ret;
+	}
+	else {
+		Py_RETURN_NONE;
+	}
+}
+
 static struct PyMethodDef pyrna_struct_subtype_methods[] = {
 	{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
 	{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
 	{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
 	{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
+
+	{"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""},
 	{NULL, NULL, 0, NULL}
 };
 
@@ -2494,8 +2520,8 @@
 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self);
 static struct PyMethodDef pyrna_basetype_methods[] = {
 	{"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""},
-	{"register", (PyCFunction)pyrna_basetype_register, METH_VARARGS, ""},
-	{"unregister", (PyCFunction)pyrna_basetype_unregister, METH_VARARGS, ""},
+	{"register", (PyCFunction)pyrna_basetype_register, METH_O, ""},
+	{"unregister", (PyCFunction)pyrna_basetype_unregister, METH_O, ""},
 	{NULL, NULL, 0, NULL}
 };
 
@@ -2571,13 +2597,31 @@
 	return submodule;
 }
 
+static StructRNA *pyrna_struct_as_srna(PyObject *self)
+{
+	PyObject *py_srna= (BPy_StructRNA *)PyObject_GetAttrString(self, "__rna__");
+
+	if(py_srna==NULL) {
+	 	PyErr_SetString(PyExc_SystemError, "internal error, self had no __rna__ attribute, should never happen.");
+		return NULL;
+	}
+
+	if(!PyCObject_Check(py_srna)) {
+	 	PyErr_SetString(PyExc_SystemError, "internal error, self had no __rna__ attribute, should never happen.");
+	 	Py_DECREF(py_srna);
+		return NULL;
+	}
+
+	Py_DECREF(py_srna);
+	return (StructRNA *)PyCObject_AsVoidPtr(py_srna);
+}
+
+
 /* Orphan functions, not sure where they should go */
 /* get the srna for methods attached to types */
 /* */
 static StructRNA *srna_from_self(PyObject *self)
 {
-	BPy_StructRNA *py_srna;
-	
 	/* a bit sloppy but would cause a very confusing bug if
 	 * an error happened to be set here */
 	PyErr_Clear();
@@ -2594,30 +2638,7 @@
 	/* These cases above not errors, they just mean the type was not compatible
 	 * After this any errors will be raised in the script */
 
-	
-	py_srna= (BPy_StructRNA *)PyObject_GetAttrString(self, "__rna__");
-
-	if(py_srna==NULL) {
-	 	PyErr_SetString(PyExc_SystemError, "internal error, self had no __rna__ attribute, should never happen.");
-		return NULL;
-	}
-
-	if(!BPy_StructRNA_Check(py_srna)) {
-	 	PyErr_SetString(PyExc_SystemError, "internal error, self's __rna__ attribute isnt a StructRNA type, should never happen.");
-		return NULL;
-	}
-
-	if((py_srna->ptr.data && py_srna->ptr.type == &RNA_Struct) == 0) {
-	 	PyErr_SetString(PyExc_SystemError, "internal error, self's __rna__ attribute wasnt an RNA_Struct, should never happen.");
-		return NULL;
-	}
-
-	if(!RNA_struct_is_ID(py_srna->ptr.data)) {
-		PyErr_SetString(PyExc_TypeError, "only ID types support python defined properties");
-		return NULL;
-	}
-
-	return py_srna->ptr.data;
+	return pyrna_struct_as_srna(self);
 }
 
 /* operators use this so it can store the args given but defer running
@@ -3029,43 +3050,19 @@
 	RNA_PROP_END;
 }
 
-PyObject *pyrna_basetype_register(PyObject *self, PyObject *args)
+PyObject *pyrna_basetype_register(PyObject *self, PyObject *py_class)
 {
 	bContext *C= NULL;
-	PyObject *py_class, *item;
 	ReportList reports;
 	StructRegisterFunc reg;
-	BPy_StructRNA *py_srna;
 	StructRNA *srna;
 
-	if(!PyArg_ParseTuple(args, "O:register", &py_class))
+	srna= pyrna_struct_as_srna(py_class);
+	if(srna==NULL)
 		return NULL;
 	
-	if(!PyType_Check(py_class)) {
-		PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no a Type object).");
-		return NULL;
-	}
-
-	/* check we got an __rna__ attribute */
-	item= PyObject_GetAttrString(py_class, "__rna__");
-
-	if(!item || !BPy_StructRNA_Check(item)) {
-		Py_XDECREF(item);
-		PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no __rna__ property).");
-		return NULL;
-	}
-
-	/* check the __rna__ attribute has the right type */
-	Py_DECREF(item);
-	py_srna= (BPy_StructRNA*)item;
-
-	if(py_srna->ptr.type != &RNA_Struct) {
-		PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (not a Struct).");
-		return NULL;
-	}
-	
 	/* check that we have a register callback for this type */
-	reg= RNA_struct_register(py_srna->ptr.data);
+	reg= RNA_struct_register(srna);
 
 	if(!reg) {
 		PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no register supported).");
@@ -3092,39 +3089,18 @@
 	Py_RETURN_NONE;
 }
 
-PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args)
+PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *py_class)
 {
 	bContext *C= NULL;
-	PyObject *py_class, *item;
-	BPy_StructRNA *py_srna;
 	StructUnregisterFunc unreg;
+	StructRNA *srna;
 
-	if(!PyArg_ParseTuple(args, "O:unregister", &py_class))
+	srna= pyrna_struct_as_srna(py_class);
+	if(srna==NULL)
 		return NULL;
-
-	if(!PyType_Check(py_class)) {
-		PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no a Type object).");
-		return NULL;
-	}
-
-	/* check we got an __rna__ attribute */
-	item= PyDict_GetItemString(((PyTypeObject*)py_class)->tp_dict, "__rna__");  /* borrow ref */
-
-	if(!item || !BPy_StructRNA_Check(item)) {
-		PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no __rna__ property).");
-		return NULL;
-	}
-
-	/* check the __rna__ attribute has the right type */
-	py_srna= (BPy_StructRNA*)item;
-
-	if(py_srna->ptr.type != &RNA_Struct) {
-		PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (not a Struct).");
-		return NULL;
-	}
 	
 	/* check that we have a unregister callback for this type */
-	unreg= RNA_struct_unregister(py_srna->ptr.data);
+	unreg= RNA_struct_unregister(srna);
 
 	if(!unreg) {
 		PyErr_SetString(PyExc_AttributeError, "expected a Type subclassed from a registerable rna type (no unregister supported).");
@@ -3136,7 +3112,7 @@
 	
 
 	/* call unregister */
-	unreg(C, py_srna->ptr.data);
+	unreg(C, srna);
 
 	/* remove reference to old type */
 	Py_DECREF(py_class);





More information about the Bf-blender-cvs mailing list