[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35271] trunk/blender/source/blender/ python/intern: bpy/rna support for invalidating objects.

Campbell Barton ideasman42 at gmail.com
Mon Feb 28 23:56:30 CET 2011


Revision: 35271
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35271
Author:   campbellbarton
Date:     2011-02-28 22:56:29 +0000 (Mon, 28 Feb 2011)
Log Message:
-----------
bpy/rna support for invalidating objects.
access will raise an error.

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

Modified: trunk/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_rna.c	2011-02-28 21:06:09 UTC (rev 35270)
+++ trunk/blender/source/blender/python/intern/bpy_rna.c	2011-02-28 22:56:29 UTC (rev 35271)
@@ -69,6 +69,43 @@
 
 static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
 
+#define PYRNA_STRUCT_CHECK_OBJ(obj) if(pyrna_struct_validity_check(obj) == -1) { return NULL; }
+#define PYRNA_STRUCT_CHECK_INT(obj) if(pyrna_struct_validity_check(obj) == -1) { return -1; }
+
+#define PYRNA_PROP_CHECK_OBJ(obj) if(pyrna_prop_validity_check(obj) == -1) { return NULL; }
+#define PYRNA_PROP_CHECK_INT(obj) if(pyrna_prop_validity_check(obj) == -1) { return -1; }
+
+#define PYRNA_STRUCT_IS_VALID(pysrna) (((BPy_StructRNA *)(pysrna))->ptr.type != NULL)
+#define PYRNA_PROP_IS_VALID(pysrna) (((BPy_PropertyRNA *)(pysrna))->ptr.type != NULL)
+
+static int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
+{
+	if(pysrna->ptr.type)
+		return 0;
+	PyErr_Format(PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name);
+	return -1;
+}
+
+static int pyrna_prop_validity_check(BPy_PropertyRNA *self)
+{
+	if(self->ptr.type)
+		return 0;
+	PyErr_Format(PyExc_ReferenceError, "PropertyRNA of type %.200s.%.200s has been removed", Py_TYPE(self)->tp_name, RNA_property_identifier(self->prop));
+	return -1;
+}
+
+/*
+static void pyrna_struct_invalidate(BPy_StructRNA *self)
+{
+	self->ptr.type= NULL;
+}
+
+static void pyrna_prop_invalidate(BPy_PropertyRNA *self)
+{
+	self->ptr.type= NULL;
+}
+*/
+
 #ifdef USE_PEDANTIC_WRITE
 static short rna_disallow_writes= FALSE;
 
@@ -130,12 +167,18 @@
 static int mathutils_rna_generic_check(BaseMathObject *bmo)
 {
 	BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
+
+	PYRNA_PROP_CHECK_INT(self)
+
 	return self->prop ? 0 : -1;
 }
 
 static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype)
 {
 	BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
+
+	PYRNA_PROP_CHECK_INT(self)
+
 	if(self->prop==NULL)
 		return -1;
 
@@ -155,6 +198,9 @@
 {
 	BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
 	float min, max;
+
+	PYRNA_PROP_CHECK_INT(self)
+
 	if(self->prop==NULL)
 		return -1;
 
@@ -202,6 +248,8 @@
 {
 	BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
 
+	PYRNA_PROP_CHECK_INT(self)
+
 	if(self->prop==NULL)
 		return -1;
 
@@ -213,6 +261,8 @@
 {
 	BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
 
+	PYRNA_PROP_CHECK_INT(self)
+
 	if(self->prop==NULL)
 		return -1;
 
@@ -253,6 +303,8 @@
 {
 	BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
 
+	PYRNA_PROP_CHECK_INT(self)
+
 	if(self->prop==NULL)
 		return -1;
 
@@ -264,6 +316,8 @@
 {
 	BPy_PropertyRNA *self= (BPy_PropertyRNA *)bmo->cb_user;
 
+	PYRNA_PROP_CHECK_INT(self)
+
 	if(self->prop==NULL)
 		return -1;
 
@@ -453,12 +507,12 @@
 	return 0;
 }
 
-static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
+static int pyrna_struct_compare(BPy_StructRNA *a, BPy_StructRNA *b)
 {
 	return (a->ptr.data==b->ptr.data) ? 0 : -1;
 }
 
-static int pyrna_prop_compare( BPy_PropertyRNA * a, BPy_PropertyRNA * b )
+static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b)
 {
 	return (a->prop==b->prop && a->ptr.data==b->ptr.data ) ? 0 : -1;
 }
@@ -522,11 +576,15 @@
 }
 
 /*----------------------repr--------------------------------------------*/
-static PyObject *pyrna_struct_str( BPy_StructRNA *self )
+static PyObject *pyrna_struct_str(BPy_StructRNA *self)
 {
 	PyObject *ret;
 	const char *name;
 
+	if(!PYRNA_STRUCT_IS_VALID(self)) {
+		return PyUnicode_FromFormat("<bpy_struct, %.200s dead>", Py_TYPE(self)->tp_name);
+	}
+
 	/* print name if available */
 	name= RNA_struct_name_get_alloc(&self->ptr, NULL, FALSE);
 	if(name) {
@@ -541,7 +599,7 @@
 static PyObject *pyrna_struct_repr(BPy_StructRNA *self)
 {
 	ID *id= self->ptr.id.data;
-	if(id == NULL)
+	if(id == NULL || !PYRNA_STRUCT_IS_VALID(self))
 		return pyrna_struct_str(self); /* fallback */
 
 	if(RNA_struct_is_ID(self->ptr.type)) {
@@ -563,15 +621,19 @@
 	}
 }
 
-static PyObject *pyrna_prop_str( BPy_PropertyRNA *self )
+static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
 {
 	PyObject *ret;
 	PointerRNA ptr;
 	const char *name;
 	const char *type_id= NULL;
 	char type_fmt[64]= "";
-	int type= RNA_property_type(self->prop);
+	int type;
 
+	PYRNA_PROP_CHECK_OBJ(self)
+
+	type= RNA_property_type(self->prop);
+
 	if(RNA_enum_id_from_value(property_type_items, type, &type_id)==0) {
 		PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); /* should never happen */
 		return NULL;
@@ -616,11 +678,13 @@
 
 static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
 {
-	ID *id= self->ptr.id.data;
+	ID *id;
 	PyObject *ret;
 	const char *path;
 
-	if(id == NULL)
+	PYRNA_PROP_CHECK_OBJ(self)
+
+	if((id= self->ptr.id.data))
 		return pyrna_prop_str(self); /* fallback */
 
 	path= RNA_path_from_ID_to_property(&self->ptr, self->prop);
@@ -635,7 +699,7 @@
 	return ret;
 }
 
-static long pyrna_struct_hash( BPy_StructRNA *self )
+static long pyrna_struct_hash(BPy_StructRNA *self)
 {
 	return _Py_HashPointer(self->ptr.data);
 }
@@ -1350,8 +1414,9 @@
 	return 0;
 }
 
-static PyObject * pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
+static PyObject *pyrna_prop_array_to_py_index(BPy_PropertyArrayRNA *self, int index)
 {
+	PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
 	return pyrna_py_from_array_index(self, &self->ptr, self->prop, index);
 }
 
@@ -1427,14 +1492,18 @@
 //---------------sequence-------------------------------------------
 static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
 {
+	PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self)
+
 	if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1)
 		return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
 	else
 		return RNA_property_array_length(&self->ptr, self->prop);
 }
 
-static Py_ssize_t pyrna_prop_collection_length( BPy_PropertyRNA *self )
+static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
 {
+	PYRNA_PROP_CHECK_INT(self)
+
 	return RNA_property_collection_length(&self->ptr, self->prop);
 }
 
@@ -1442,15 +1511,19 @@
  * of 1000's of items in a linked list for eg. */
 static int pyrna_prop_array_bool(BPy_PropertyRNA *self)
 {
+	PYRNA_PROP_CHECK_INT(self)
+
 	return RNA_property_array_length(&self->ptr, self->prop) ? 1 : 0;
 }
 
-static int pyrna_prop_collection_bool( BPy_PropertyRNA *self )
+static int pyrna_prop_collection_bool(BPy_PropertyRNA *self)
 {
 	/* no callback defined, just iterate and find the nth item */
 	CollectionPropertyIterator iter;
 	int test;
 
+	PYRNA_PROP_CHECK_INT(self)
+
 	RNA_property_collection_begin(&self->ptr, self->prop, &iter);
 	test = iter.valid;
 	RNA_property_collection_end(&iter);
@@ -1463,6 +1536,8 @@
 	PointerRNA newptr;
 	Py_ssize_t keynum_abs= keynum;
 
+	PYRNA_PROP_CHECK_OBJ(self)
+
 	/* notice getting the length of the collection is avoided unless negative index is used
 	 * or to detect internal error with a valid index.
 	 * This is done for faster lookups. */
@@ -1493,8 +1568,12 @@
 
 static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyArrayRNA *self, int keynum)
 {
-	int len= pyrna_prop_array_length(self);
+	int len;
 
+	PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
+
+	len= pyrna_prop_array_length(self);
+
 	if(keynum < 0) keynum += len;
 
 	if(keynum >= 0 && keynum < len)
@@ -1507,6 +1586,9 @@
 static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, const char *keyname)
 {
 	PointerRNA newptr;
+
+	PYRNA_PROP_CHECK_OBJ(self)
+
 	if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
 		return pyrna_struct_CreatePyObject(&newptr);
 
@@ -1517,13 +1599,17 @@
 
 static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
 {
+	CollectionPropertyIterator rna_macro_iter;
 	int count= 0;
 
-	PyObject *list= PyList_New(0);
+	PyObject *list;
 	PyObject *item;
 
+	PYRNA_PROP_CHECK_OBJ(self)
+
+	list= PyList_New(0);
+
 	/* first loop up-until the start */
-	CollectionPropertyIterator rna_macro_iter;
 	for(RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
 		/* PointerRNA itemptr= rna_macro_iter.ptr; */
 		if(count == start) {
@@ -1556,9 +1642,14 @@
 static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
 {
 	int count, totdim;
+	PyObject *tuple;
 
-	PyObject *tuple= PyTuple_New(stop - start);
+	PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
 
+	tuple= PyTuple_New(stop - start);
+
+	/* PYRNA_PROP_CHECK_OBJ(self) isnt needed, internal use only */
+
 	totdim = RNA_property_array_dimension(ptr, prop, NULL);
 
 	if (totdim > 1) {
@@ -1628,6 +1719,8 @@
 
 static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject *key)
 {
+	PYRNA_PROP_CHECK_OBJ(self)
+
 	if (PyUnicode_Check(key)) {
 		return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
 	}
@@ -1682,6 +1775,8 @@
 
 static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
 {
+	PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self)
+
 	/*if (PyUnicode_Check(key)) {
 		return pyrna_prop_array_subscript_str(self, _PyUnicode_AsString(key));
 	} else*/
@@ -1833,8 +1928,12 @@
 
 static int prop_subscript_ass_array_int(BPy_PropertyArrayRNA *self, Py_ssize_t keynum, PyObject *value)
 {
-	int len= pyrna_prop_array_length(self);
+	int len;
 
+	PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self)
+
+	len= pyrna_prop_array_length(self);
+
 	if(keynum < 0) keynum += len;
 
 	if(keynum >= 0 && keynum < len)
@@ -1844,11 +1943,13 @@
 	return -1;
 }
 
-static int pyrna_prop_array_ass_subscript( BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value )
+static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value)
 {
 	/* char *keyname = NULL; */ /* not supported yet */
 	int ret= -1;
 
+	PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self)
+
 	if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
 		PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) );
 		ret= -1;
@@ -1962,6 +2063,8 @@
 	IDProperty *group;

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list