PyRNA api wasnt using python subclasses most of the time.
authorCampbell Barton <ideasman42@gmail.com>
Fri, 10 Jul 2009 04:25:49 +0000 (04:25 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 10 Jul 2009 04:25:49 +0000 (04:25 +0000)
Now this will return True
 isinstance(bpy.data.meshes[0], bpy.types.Mesh)

Use the StructRNA identifier for the new classes name properties because classes were being named by the data names rather then the type names.

Set the __module__ for the new type which makes printing the class not use the script name where the type is first initialized.
 eg: bpy.types.Mesh instead of buttons_object.Mesh

This still isnt quite right since opertators and panels all get their own type, when they should all use an operator type.

source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_access.c
source/blender/python/intern/bpy_rna.c

index e145722428cc10ebe01530a4f7dbf636f8115a33..3b2520c41b248d15aff9c0ca6d25d47c20585582 100644 (file)
@@ -496,6 +496,7 @@ int RNA_struct_ui_icon(StructRNA *type);
 
 PropertyRNA *RNA_struct_name_property(StructRNA *type);
 PropertyRNA *RNA_struct_iterator_property(StructRNA *type);
+StructRNA *RNA_struct_base(StructRNA *type);
 
 int RNA_struct_is_ID(StructRNA *type);
 int RNA_struct_is_a(StructRNA *type, StructRNA *srna);
index cc8704dc35058e207a3795edf937edd1f5012a63..eb53d0fbf51408bc12df253bf070654d01fdf143 100644 (file)
@@ -392,6 +392,11 @@ PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
        return type->iteratorproperty;
 }
 
+StructRNA *RNA_struct_base(StructRNA *type)
+{
+       return type->base;
+}
+
 int RNA_struct_is_ID(StructRNA *type)
 {
        return (type->flag & STRUCT_ID) != 0;
index bf2f41389cc457102974069038b9885c4fb689ca..8314a3cc89c3c288feed5048d74bd203c163c3f2 100644 (file)
@@ -2175,40 +2175,54 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
 PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
 {
        PyObject *newclass = NULL;
-       PropertyRNA *nameprop;
+       StructRNA *srna, *base;
+       
+       if(ptr->type == &RNA_Struct)
+               srna= ptr->data;
+       else
+               srna= ptr->type;
 
-       if (ptr->type==NULL) {
+       if (srna == NULL) {
                newclass= NULL; /* Nothing to do */
-       } else if ((newclass= RNA_struct_py_type_get(ptr->data))) {
+       } else if ((newclass= RNA_struct_py_type_get(srna))) {
                Py_INCREF(newclass);
-       } else if ((nameprop = RNA_struct_name_property(ptr->type))) {
+       } else {
                /* for now, return the base RNA type rather then a real module */
                
-               /* Assume RNA_struct_py_type_get(ptr->data) was alredy checked */
+               /* Assume RNA_struct_py_type_get(srna) was alredy checked */
                
                /* subclass equivelents
                - class myClass(myBase):
                        some='value' # or ...
-               - myClass = type(name='myClass', bases=(myBase,), dict={'some':'value'})
+               - myClass = type(name='myClass', bases=(myBase,), dict={'__module__':'bpy.types'})
                */
-               char name[256], *nameptr;
-               const char *descr= RNA_struct_ui_description(ptr->type);
+               const char *descr= RNA_struct_ui_description(srna);
 
                PyObject *args = PyTuple_New(3);
                PyObject *bases = PyTuple_New(1);
+               PyObject *py_base= NULL;
                PyObject *dict = PyDict_New();
                PyObject *item;
                
                
-               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));
+               PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(RNA_struct_identifier(srna)));
                
                // arg 2
-               PyTuple_SET_ITEM(bases, 0, (PyObject *)&pyrna_struct_Type);
-               Py_INCREF(&pyrna_struct_Type);
+#if 0  // XXX - This should be possible but for some reason it does a recursive call for MirrorModifier
+               base= RNA_struct_base(srna);
+               if(base && base != srna) {
+                       // printf("debug subtype %s\n", RNA_struct_identifier(srna));
+                       py_base= pyrna_struct_Subtype(base);
+               }
+#endif
+               if(py_base==NULL) {
+                       py_base= &pyrna_struct_Type;
+                       Py_INCREF(py_base);
+               }
+               
+               PyTuple_SET_ITEM(bases, 0, py_base);
 
                PyTuple_SET_ITEM(args, 1, bases);
                
@@ -2219,6 +2233,13 @@ PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
                        Py_DECREF(item);
                }
                
+               /* this isnt needed however its confusing if we get python script names in blender types,
+                * because the __module__ is used when printing the class */
+               item= PyUnicode_FromString("bpy.types"); /* just to know its an internal type */
+               PyDict_SetItemString(dict, "__module__", item);
+               Py_DECREF(item);
+               
+               
                PyTuple_SET_ITEM(args, 2, dict); // fill with useful subclass things!
                
                if (PyErr_Occurred()) {
@@ -2229,11 +2250,15 @@ PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
                newclass = PyObject_CallObject((PyObject *)&PyType_Type, args);
                Py_DECREF(args);
 
-               if (newclass)
-                       pyrna_subtype_set_rna(newclass, ptr->data);
-               
-               if (name != nameptr)
-                       MEM_freeN(nameptr);
+               if (newclass) {
+                       pyrna_subtype_set_rna(newclass, srna);
+                       // PyObSpit("NewStructRNA Type: ", (PyObject *)newclass);
+               }
+               else {
+                       /* this should not happen */
+                       PyErr_Print();
+                       PyErr_Clear();
+               }
        }
        
        return newclass;
@@ -2247,8 +2272,7 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
        if (ptr->data==NULL && ptr->type==NULL) { /* Operator RNA has NULL data */
                Py_RETURN_NONE;
        }
-       
-       if (ptr->type == &RNA_Struct) { /* always return a python subtype from rna struct types */
+       else {
                PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr);
                
                if (tp) {
@@ -2259,10 +2283,7 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
                        pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
                }
        }
-       else {
-               pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
-       }
-       
+
        if( !pyrna ) {
                PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_StructRNA object" );
                return NULL;
@@ -2270,6 +2291,9 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
        
        pyrna->ptr= *ptr;
        pyrna->freeptr= 0;
+       
+       // PyObSpit("NewStructRNA: ", (PyObject *)pyrna);
+       
        return ( PyObject * ) pyrna;
 }