[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24450] trunk/blender: modify the python context access so invalid names will raise an exception rather then returning None .

Campbell Barton ideasman42 at gmail.com
Tue Nov 10 16:09:53 CET 2009


Revision: 24450
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24450
Author:   campbellbarton
Date:     2009-11-10 16:09:53 +0100 (Tue, 10 Nov 2009)

Log Message:
-----------
modify the python context access so invalid names will raise an exception rather then returning None.
this way the UI scripts are less likely to fail silently and wont let typos work ok.

also allow subclassing of the context, added a copy function,
 bpy.context.copy(), returns the context as a python dict to be modified and used in python.

This also showed up an invalid brush member in the screen context.

Modified Paths:
--------------
    trunk/blender/release/scripts/modules/bpy_types.py
    trunk/blender/source/blender/blenkernel/BKE_context.h
    trunk/blender/source/blender/blenkernel/intern/context.c
    trunk/blender/source/blender/editors/screen/screen_context.c
    trunk/blender/source/blender/editors/space_buttons/buttons_context.c
    trunk/blender/source/blender/editors/space_view3d/space_view3d.c
    trunk/blender/source/blender/python/intern/bpy_rna.c

Modified: trunk/blender/release/scripts/modules/bpy_types.py
===================================================================
--- trunk/blender/release/scripts/modules/bpy_types.py	2009-11-10 13:20:32 UTC (rev 24449)
+++ trunk/blender/release/scripts/modules/bpy_types.py	2009-11-10 15:09:53 UTC (rev 24450)
@@ -22,6 +22,17 @@
 # StructRNA = bpy.types.Struct
 
 
+class Context(StructRNA):
+    
+    def copy(self):
+        new_context = {}
+        for item in dir(self):
+            if item not in StructRNA.__dict__ and item != "id_data":
+                new_context[item] = getattr(self, item)
+            
+        return new_context
+
+
 class Object(bpy.types.ID):
 
     def _get_children(self):

Modified: trunk/blender/source/blender/blenkernel/BKE_context.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_context.h	2009-11-10 13:20:32 UTC (rev 24449)
+++ trunk/blender/source/blender/blenkernel/BKE_context.h	2009-11-10 15:09:53 UTC (rev 24450)
@@ -174,7 +174,7 @@
 PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
 ListBase CTX_data_collection_get(const bContext *C, const char *member);
 ListBase CTX_data_dir_get(const bContext *C);
-void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
+int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
 
 void CTX_data_id_pointer_set(bContextDataResult *result, struct ID *id);
 void CTX_data_pointer_set(bContextDataResult *result, struct ID *id, StructRNA *type, void *data);

Modified: trunk/blender/source/blender/blenkernel/intern/context.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/context.c	2009-11-10 13:20:32 UTC (rev 24449)
+++ trunk/blender/source/blender/blenkernel/intern/context.c	2009-11-10 15:09:53 UTC (rev 24450)
@@ -408,6 +408,7 @@
 static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
 {
 	int done= 0, recursion= C->data.recursion;
+	int ret= 0;
 
 	memset(result, 0, sizeof(bContextDataResult));
 
@@ -417,7 +418,14 @@
 
 	/* we check recursion to ensure that we do not get infinite
 	 * loops requesting data from ourselfs in a context callback */
-	if(!done && recursion < 1 && C->wm.store) {
+
+	/* Ok, this looks evil...
+	 * if(ret) done= -(-ret | -done);
+	 *
+	 * Values in order of importance
+	 * (0, -1, 1) - Where 1 is highest priority
+	 * */
+	if(done!=1 && recursion < 1 && C->wm.store) {
 		bContextStoreEntry *entry;
 
 		C->data.recursion= 1;
@@ -429,21 +437,28 @@
 			}
 		}
 	}
-	if(!done && recursion < 2 && C->wm.region) {
+	if(done!=1 && recursion < 2 && C->wm.region) {
 		C->data.recursion= 2;
-		if(C->wm.region->type && C->wm.region->type->context)
-			done= C->wm.region->type->context(C, member, result);
+		if(C->wm.region->type && C->wm.region->type->context) {
+			ret = C->wm.region->type->context(C, member, result);
+			if(ret) done= -(-ret | -done);
+
+		}
 	}
-	if(!done && recursion < 3 && C->wm.area) {
+	if(done!=1 && recursion < 3 && C->wm.area) {
 		C->data.recursion= 3;
-		if(C->wm.area->type && C->wm.area->type->context)
-			done= C->wm.area->type->context(C, member, result);
+		if(C->wm.area->type && C->wm.area->type->context) {
+			ret = C->wm.area->type->context(C, member, result);
+			if(ret) done= -(-ret | -done);
+		}
 	}
-	if(!done && recursion < 4 && C->wm.screen) {
+	if(done!=1 && recursion < 4 && C->wm.screen) {
 		bContextDataCallback cb= C->wm.screen->context;
 		C->data.recursion= 4;
-		if(cb)
-			done= cb(C, member, result);
+		if(cb) {
+			ret = cb(C, member, result);
+			if(ret) done= -(-ret | -done);
+		}
 	}
 
 	C->data.recursion= recursion;
@@ -455,7 +470,7 @@
 {
 	bContextDataResult result;
 
-	if(C && ctx_data_get((bContext*)C, member, &result))
+	if(C && ctx_data_get((bContext*)C, member, &result)==1)
 		return result.ptr.data;
 
 	return NULL;
@@ -465,7 +480,7 @@
 {
 	bContextDataResult result;
 
-	if(ctx_data_get((bContext*)C, member, &result)) {
+	if(ctx_data_get((bContext*)C, member, &result)==1) {
 		*pointer= result.ptr.data;
 		return 1;
 	}
@@ -479,7 +494,7 @@
 {
 	bContextDataResult result;
 
-	if(ctx_data_get((bContext*)C, member, &result)) {
+	if(ctx_data_get((bContext*)C, member, &result)==1) {
 		*list= result.list;
 		return 1;
 	}
@@ -494,7 +509,7 @@
 {
 	bContextDataResult result;
 
-	if(ctx_data_get((bContext*)C, member, &result))
+	if(ctx_data_get((bContext*)C, member, &result)==1)
 		return result.ptr;
 	else
 		return PointerRNA_NULL;
@@ -514,7 +529,7 @@
 {
 	bContextDataResult result;
 
-	if(ctx_data_get((bContext*)C, member, &result)) {
+	if(ctx_data_get((bContext*)C, member, &result)==1) {
 		return result.list;
 	}
 	else {
@@ -524,11 +539,13 @@
 	}
 }
 
-void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
+/* 1:found,  -1:found but not set,  0:not found */
+int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
 {
 	bContextDataResult result;
+	int ret= ctx_data_get((bContext*)C, member, &result);
 
-	if(ctx_data_get((bContext*)C, member, &result)) {
+	if(ret==1) {
 		*r_ptr= result.ptr;
 		*r_lb= result.list;
 	}
@@ -536,6 +553,8 @@
 		memset(r_ptr, 0, sizeof(*r_ptr));
 		memset(r_lb, 0, sizeof(*r_lb));
 	}
+
+	return ret;
 }
 
 static void data_dir_add(ListBase *lb, const char *member)

Modified: trunk/blender/source/blender/editors/screen/screen_context.c
===================================================================
--- trunk/blender/source/blender/editors/screen/screen_context.c	2009-11-10 13:20:32 UTC (rev 24449)
+++ trunk/blender/source/blender/editors/screen/screen_context.c	2009-11-10 15:09:53 UTC (rev 24450)
@@ -67,7 +67,7 @@
 			"visible_pchans", "selected_pchans", "active_bone", "active_pchan",
 			"active_base", "active_object", "edit_object",
 			"sculpt_object", "vertex_paint_object", "weight_paint_object",
-			"texture_paint_object", "brush", "particle_edit_object", NULL};
+			"texture_paint_object", "particle_edit_object", NULL};
 
 		CTX_data_dir_set(result, dir);
 		return 1;
@@ -304,7 +304,10 @@
 
 		return 1;
 	}
+	else {
+		return 0; /* not found */
+	}
 
-	return 0;
+	return -1; /* found but not available */
 }
 

Modified: trunk/blender/source/blender/editors/space_buttons/buttons_context.c
===================================================================
--- trunk/blender/source/blender/editors/space_buttons/buttons_context.c	2009-11-10 13:20:32 UTC (rev 24449)
+++ trunk/blender/source/blender/editors/space_buttons/buttons_context.c	2009-11-10 15:09:53 UTC (rev 24450)
@@ -707,8 +707,11 @@
 		set_pointer_type(path, result, &RNA_Brush);
 		return 1;
 	}
+	else {
+		return 0; /* not found */
+	}
 
-	return 0;
+	return -1; /* found but not available */
 }
 
 /************************* Drawing the Path ************************/

Modified: trunk/blender/source/blender/editors/space_view3d/space_view3d.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/space_view3d.c	2009-11-10 13:20:32 UTC (rev 24449)
+++ trunk/blender/source/blender/editors/space_view3d/space_view3d.c	2009-11-10 15:09:53 UTC (rev 24450)
@@ -747,7 +747,11 @@
 		
 		return 1;
 	}
-	return 0;
+	else {
+		return 0; /* not found */
+	}
+
+	return -1; /* found but not available */
 }
 
 /* only called once, from space/spacetypes.c */

Modified: trunk/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_rna.c	2009-11-10 13:20:32 UTC (rev 24449)
+++ trunk/blender/source/blender/python/intern/bpy_rna.c	2009-11-10 15:09:53 UTC (rev 24450)
@@ -1376,27 +1376,38 @@
 	else if (self->ptr.type == &RNA_Context) {
 		PointerRNA newptr;
 		ListBase newlb;
+		int done;
 
-		CTX_data_get(self->ptr.data, name, &newptr, &newlb);
+		done= CTX_data_get(self->ptr.data, name, &newptr, &newlb);
 
-        if (newptr.data) {
-            ret = pyrna_struct_CreatePyObject(&newptr);
-		}
-		else if (newlb.first) {
-			CollectionPointerLink *link;
-			PyObject *linkptr;
+		if(done==1) { /* found */
+			if (newptr.data) {
+				ret = pyrna_struct_CreatePyObject(&newptr);
+			}
+			else if (newlb.first) {
+				CollectionPointerLink *link;
+				PyObject *linkptr;
 
-			ret = PyList_New(0);
+				ret = PyList_New(0);
 
-			for(link=newlb.first; link; link=link->next) {
-				linkptr= pyrna_struct_CreatePyObject(&link->ptr);
-				PyList_Append(ret, linkptr);
-				Py_DECREF(linkptr);
+				for(link=newlb.first; link; link=link->next) {
+					linkptr= pyrna_struct_CreatePyObject(&link->ptr);
+					PyList_Append(ret, linkptr);
+					Py_DECREF(linkptr);
+				}
 			}
+			else {
+				ret = Py_None;
+				Py_INCREF(ret);
+			}
 		}
-        else {
-            ret = Py_None;
-            Py_INCREF(ret);
+		else if (done==-1) { /* found but not set */
+			ret = Py_None;
+			Py_INCREF(ret);
+		}
+        else { /* not found in the context */
+        	/* lookup the subclass. raise an error if its not found */
+        	ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
         }
 
 		BLI_freelistN(&newlb);
@@ -1405,10 +1416,11 @@
 		if(self->ptr.id.data) {
 			PointerRNA id_ptr;
 			RNA_id_pointer_create((ID *)self->ptr.id.data, &id_ptr);
-			return pyrna_struct_CreatePyObject(&id_ptr);
+			ret = pyrna_struct_CreatePyObject(&id_ptr);
 		}
 		else {
-			Py_RETURN_NONE;
+			ret = Py_None;
+			Py_INCREF(ret);
 		}
 	}
 	else {





More information about the Bf-blender-cvs mailing list