[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19271] branches/blender2.5/blender/source /blender/python: 2.5 Python api

Campbell Barton ideasman42 at gmail.com
Fri Mar 13 08:50:08 CET 2009


Revision: 19271
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19271
Author:   campbellbarton
Date:     2009-03-13 08:50:07 +0100 (Fri, 13 Mar 2009)

Log Message:
-----------
2.5 Python api
- rearranged modules bpyui -> bpy.ui, bpy -> bpy.data, remove bpydoc
- new module bpy.types, stores a list of all struct types
- added __rna__ attribute to types - eg bpy.types.World.__rna__ so you can access the rna data from a type. (so bpydoc.structs isnt needed anymore)
- removed unused subtyping method (use python subclassing rather then C PyTypeObject)

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

Modified: branches/blender2.5/blender/source/blender/python/epy_doc_gen.py
===================================================================
--- branches/blender2.5/blender/source/blender/python/epy_doc_gen.py	2009-03-12 19:36:59 UTC (rev 19270)
+++ branches/blender2.5/blender/source/blender/python/epy_doc_gen.py	2009-03-13 07:50:07 UTC (rev 19271)
@@ -121,14 +121,21 @@
 		try:		return rna_struct.base.identifier
 		except:	return '' # invalid id
 
-	#structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpydoc.structs.values()]
-	
+	#structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()]
+	'''
 	structs = []
-	for rna_struct in bpydoc.structs.values():
+	for rna_struct in bpy.doc.structs.values():
 		structs.append( (base_id(rna_struct), rna_struct.identifier, rna_struct) )
-		
+	'''
+	structs = []
+	for rna_type_name in dir(bpy.types):
+		rna_type = getattr(bpy.types, rna_type_name)
+		if hasattr(rna_type, '__rna__'):
+			rna_struct = rna_type.__rna__
+			structs.append( (base_id(rna_struct), rna_struct.identifier, rna_struct) )	
 	
 	
+	
 	structs.sort() # not needed but speeds up sort below, setting items without an inheritance first
 	
 	# Arrange so classes are always defined in the correct order
@@ -178,7 +185,7 @@
 def op2epy(target_path):
 	out = open(target_path, 'w')
 	
-	operators = dir(bpyoperator)
+	operators = dir(bpy.ops)
 	operators.remove('add')
 	operators.remove('remove')
 	operators.sort()
@@ -193,7 +200,7 @@
 		kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'"
 		kw_arg_attrs = [] # "@type mode: int"
 		
-		rna = getattr(bpyoperator, op).rna
+		rna = getattr(bpy.ops, op).rna
 		rna_struct = rna.rna_type
 		# print (dir(rna))
 		# print (dir(rna_struct))

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c	2009-03-12 19:36:59 UTC (rev 19270)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_interface.c	2009-03-13 07:50:07 UTC (rev 19271)
@@ -34,31 +34,24 @@
 
 static PyObject *CreateGlobalDictionary( bContext *C )
 {
+	PyObject *mod;
 	PyObject *dict = PyDict_New(  );
 	PyObject *item = PyUnicode_FromString( "__main__" );
 	PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
 	PyDict_SetItemString( dict, "__name__", item );
 	Py_DECREF(item);
 	
-	/* Add Modules */
-	item = BPY_rna_module();
-	PyDict_SetItemString( dict, "bpy", item );
-	Py_DECREF(item);
+	/* add bpy to global namespace */
+	mod = PyModule_New("bpy");
+	PyDict_SetItemString( dict, "bpy", mod );
+	Py_DECREF(mod);
 	
-	item = BPY_rna_doc();
-	PyDict_SetItemString( dict, "bpydoc", item );
-	Py_DECREF(item);
-
-	item = BPY_operator_module(C);
-	PyDict_SetItemString( dict, "bpyoperator", item );
-	Py_DECREF(item);
-
+	PyModule_AddObject( mod, "data", BPY_rna_module() );
+	/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
+	PyModule_AddObject( mod, "types", BPY_rna_types() );
+	PyModule_AddObject( mod, "ops", BPY_operator_module(C) );
+	PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
 	
-	// XXX very experemental, consiter this a test, especiall PyCObject is not meant to be perminant
-	item = BPY_ui_module();
-	PyDict_SetItemString( dict, "bpyui", item );
-	Py_DECREF(item);
-	
 	// XXX - evil, need to access context
 	item = PyCObject_FromVoidPtr( C, NULL );
 	PyDict_SetItemString( dict, "__bpy_context__", item );
@@ -80,8 +73,6 @@
 	
 	// todo - sys paths - our own imports
 	
-	BPY_rna_init_types();
-	
 	py_tstate = PyGILState_GetThisThreadState();
 	PyEval_ReleaseThread(py_tstate);
 	
@@ -96,7 +87,6 @@
 	
 	Py_Finalize(  );
 	
-	BPY_rna_free_types(); /* this MUST run after Py_Finalize since it frees Dynamic allocated PyTypes so we cant free them first */
 	return;
 }
 

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2009-03-12 19:36:59 UTC (rev 19270)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2009-03-13 07:50:07 UTC (rev 19271)
@@ -30,12 +30,6 @@
 #include "MEM_guardedalloc.h"
 #include "BKE_global.h" /* evil G.* */
 
-/* There are 2 ways subclassing can work, PY_CLASS_SUBTYPE - Uses pythons internal subclassing
- * - class MyClass(SomeClass): ...
- * When PY_CLASS_SUBTYPE is not defined use a C subclass which copies the PyTypeObject and makes some changes.
-*/
-#define PY_CLASS_SUBTYPE
-
 static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
 {
 	return (a->ptr.data==b->ptr.data) ? 0 : -1;
@@ -1016,6 +1010,72 @@
 	NULL
 };
 
+PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
+{
+	PyObject *newclass = NULL;
+	PropertyRNA *nameprop;
+
+	if (ptr->type==NULL) {
+		newclass= NULL; /* Nothing to do */
+	} else if ((nameprop = RNA_struct_name_property(ptr))) {
+		/* for now, return the base RNA type rather then a real module */
+		
+		/* Assume BPy_RNA_PYTYPE(ptr->data) was alredy checked */
+		
+		/* subclass equivelents
+		- class myClass(myBase):
+			some='value' # or ...
+		- myClass = type(name='myClass', bases=(myBase,), dict={'some':'value'})
+		*/
+		char name[256], *nameptr;
+
+		PyObject *args = PyTuple_New(3);
+		PyObject *bases = PyTuple_New(1);
+		PyObject *dict = PyDict_New();
+		PyObject *rna;
+		
+		nameptr= RNA_property_string_get_alloc(ptr, nameprop, name, sizeof(name));
+		
+		// arg 1
+		//PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(tp_name));
+		PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(nameptr));
+		
+		// arg 2
+		PyTuple_SET_ITEM(bases, 0, (PyObject *)&pyrna_struct_Type);
+		Py_INCREF(&pyrna_struct_Type);
+		PyTuple_SET_ITEM(args, 1, bases);
+		
+		// arg 3 - add an instance of the rna 
+		PyTuple_SET_ITEM(args, 2, dict); // fill with useful subclass things!
+		
+		if (PyErr_Occurred()) {
+			PyErr_Print();
+			PyErr_Clear();
+		}
+		
+		newclass = PyObject_CallObject((PyObject *)&PyType_Type, args);
+		// Set this later
+		
+		if (newclass) {
+			BPy_RNA_PYTYPE(ptr->data) = newclass; /* Store for later use */
+			
+			/* Not 100% needed but useful,
+			 * having an instance within a type looks wrong however this instance IS an rna type */
+			rna = pyrna_struct_CreatePyObject(ptr);
+			PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", rna);
+			Py_DECREF(rna);
+			/* done with rna instance */
+		}
+		Py_DECREF(args);
+		
+		if ((char *)&name != nameptr)
+			MEM_freeN(nameptr);
+		
+	}
+	
+	return newclass;
+}
+
 /*-----------------------CreatePyObject---------------------------------*/
 PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
 {
@@ -1025,7 +1085,6 @@
 		Py_RETURN_NONE;
 	}
 	
-#ifdef PY_CLASS_SUBTYPE
 	pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
 	if (ptr->type && BPy_RNA_PYTYPE(ptr->type)) {
 		PyTypeObject *tp = BPy_RNA_PYTYPE(ptr->type);
@@ -1035,18 +1094,6 @@
 		pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
 	}
 	
-#else
-	/* get subtype from RNA struct if its been set */
-	PyTypeObject *tp;
-	if (ptr->type && ptr->type)
-		tp = BPy_RNA_PYTYPE(ptr->type);
-	
-	if (tp==NULL)
-		tp= &pyrna_struct_Type;
-	
-	pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, tp );
-#endif	
-	
 	if( !pyrna ) {
 		PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_StructRNA object" );
 		return NULL;
@@ -1080,15 +1127,24 @@
 {
 	PointerRNA ptr;
 	
-	/* types init moved to BPY_rna_init_types */
+	/* This can't be set in the pytype struct because some compilers complain */
+	pyrna_prop_Type.tp_getattro = PyObject_GenericGetAttr; 
+	pyrna_prop_Type.tp_setattro = PyObject_GenericSetAttr; 
 	
+	if( PyType_Ready( &pyrna_struct_Type ) < 0 )
+		return NULL;
+	
+	if( PyType_Ready( &pyrna_prop_Type ) < 0 )
+		return NULL;
+
+	
 	/* for now, return the base RNA type rather then a real module */
 	RNA_main_pointer_create(G.main, &ptr);
 	
-	//submodule = Py_InitModule3( "rna", M_rna_methods, "rna module" );
 	return pyrna_struct_CreatePyObject(&ptr);
 }
 
+#if 0
 /* This is a way we can access docstrings for RNA types
  * without having the datatypes in blender */
 PyObject *BPY_rna_doc( void )
@@ -1100,204 +1156,48 @@
 	
 	return pyrna_struct_CreatePyObject(&ptr);
 }
+#endif
 
-#ifdef PY_CLASS_SUBTYPE
-void BPY_rna_init_types(void)
-{	
+ PyObject *BPY_rna_types(void)
+ {
 	/* Now initialize new subtypes based on pyrna_struct_Type */
-	char tp_name[64];
 	PointerRNA ptr;
 
 	CollectionPropertyIterator iter;
-	PropertyRNA *nameprop, *prop;
-	char name[256], *nameptr;
+	PropertyRNA *prop;
 
+	PyObject *mod, *dict, *type, *name;
+ 
+	mod = PyModule_New("types");
+	dict = PyModule_GetDict(mod);
 	
-	/* This can't be set in the pytype struct because some compilers complain */
-	pyrna_prop_Type.tp_getattro = PyObject_GenericGetAttr; 
-	pyrna_prop_Type.tp_setattro = PyObject_GenericSetAttr; 
-	
-	if( PyType_Ready( &pyrna_struct_Type ) < 0 )
-		return;
-	
-	if( PyType_Ready( &pyrna_prop_Type ) < 0 )
-		return;
-		
-	
 	/* for now, return the base RNA type rather then a real module */
 	RNA_blender_rna_pointer_create(&ptr);
 	prop = RNA_struct_find_property(&ptr, "structs");
 	
 	RNA_property_collection_begin(&ptr, prop, &iter);
 	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
-			
-			/* subclass = type(name='myClass', bases=(myBase,), dict={'some':'value'}) */
-			PyObject *args = PyTuple_New(3);
-			PyObject *bases = PyTuple_New(1);
-			PyObject *dict = PyDict_New();
-			PyObject *newclass;
-			
-			nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
-			snprintf(tp_name, 64, "BPyRNA_%s", nameptr);
-			
-			
-			// arg 1
-			PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(tp_name));
-			
-			// arg 2
-			PyTuple_SET_ITEM(bases, 0, (PyObject *)&pyrna_struct_Type);
-			Py_INCREF(&pyrna_struct_Type);
-			PyTuple_SET_ITEM(args, 1, bases);
-			
-			// arg 3
-			PyTuple_SET_ITEM(args, 2, dict); // fill with useful subclass things!
-			
-			if (PyErr_Occurred()) {
-				PyErr_Print();
-				PyErr_Clear();
+		if(iter.ptr.data) {
+			type = (PyObject *)BPy_RNA_PYTYPE(iter.ptr.data);
+			if (type==NULL) {
+				type = pyrna_struct_Subtype(&iter.ptr);
 			}
-			

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list