Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/makesrna/intern/makesrna.c4
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h4
-rw-r--r--source/blender/python/epy_doc_gen.py1
-rw-r--r--source/blender/python/intern/bpy_interface.c7
-rw-r--r--source/blender/python/intern/bpy_operator.c5
-rw-r--r--source/blender/python/intern/bpy_rna.c308
-rw-r--r--source/blender/python/intern/bpy_rna.h14
-rw-r--r--source/blender/python/intern/bpy_util.c2
-rw-r--r--source/blender/python/rna_dump.py112
-rw-r--r--source/blender/python/simple_enum_gen.py65
10 files changed, 483 insertions, 39 deletions
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index acc0ed5cec9..bf1246c5b9d 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -1201,7 +1201,9 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
else fprintf(f, "\tNULL, ");
if(srna->prev) fprintf(f, "&RNA_%s,\n", srna->prev->identifier);
else fprintf(f, "NULL,\n");
-
+
+ fprintf(f, "\tNULL,\n"); /* PyType - Cant initialize here */
+
fprintf(f, "\t");
rna_print_c_string(f, srna->identifier);
fprintf(f, ", %d, ", srna->flag);
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 0eea4ea5d39..0c2eedff564 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -208,6 +208,10 @@ typedef struct CollectionPropertyRNA {
struct StructRNA {
struct StructRNA *next, *prev;
+ /* python type, this is a subtype of pyrna_struct_Type but used so each struct can have its own type
+ * which is useful for subclassing RNA */
+ void *py_type;
+
/* unique identifier */
const char *identifier;
/* various options */
diff --git a/source/blender/python/epy_doc_gen.py b/source/blender/python/epy_doc_gen.py
index f14cd2f90f9..6281cc66f47 100644
--- a/source/blender/python/epy_doc_gen.py
+++ b/source/blender/python/epy_doc_gen.py
@@ -162,6 +162,7 @@ def rna2epy(target_path):
for rna_struct in structs:
+ # print(type(rna_struct))
if rna_struct.nested:
continue
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index bb315cda47a..19d8b79884f 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -80,6 +80,8 @@ void BPY_start_python( void )
// todo - sys paths - our own imports
+ BPY_rna_init_types();
+
py_tstate = PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate);
@@ -90,8 +92,11 @@ void BPY_end_python( void )
PyGILState_Ensure(); /* finalizing, no need to grab the state */
// free other python data.
+ //BPY_rna_free_types();
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;
}
@@ -123,7 +128,7 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text )
if( PyErr_Occurred( ) ) {
BPY_free_compiled_text( text );
- return NULL;
+ return 0;
}
}
py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict );
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index ec8227c670d..d158fc72c1b 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -190,10 +190,9 @@ PyObject *pyop_func_get_rna(BPy_OperatorFunc *self)
return NULL;
}
- pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); /* were not really using &ptr, overwite next */
-
/* XXX POINTER - if this 'ot' is python generated, it could be free'd */
- RNA_pointer_create(NULL, ot->srna, NULL, &pyrna->ptr);
+ RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
+ pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); /* were not really using &ptr, overwite next */
pyrna->freeptr= 1;
return (PyObject *)pyrna;
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index c4ba79d8373..fd6221d6ff9 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -30,8 +30,11 @@
#include "MEM_guardedalloc.h"
#include "BKE_global.h" /* evil G.* */
-/* floats bigger then this are displayed as inf in the docstrings */
-#define MAXFLOAT_DOC 10000000
+/* 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 )
{
@@ -565,27 +568,28 @@ static PyMappingMethods pyrna_prop_as_mapping = {
( objobjargproc ) pyrna_prop_assign_subscript, /* mp_ass_subscript */
};
-//---------------getattr--------------------------------------------
-static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
+static PyObject *pyrna_struct_dir(BPy_StructRNA * self)
{
- char *name = _PyUnicode_AsString(pyname);
- PyObject *ret;
- PropertyRNA *prop;
+ PyObject *ret, *dict;
+ PyObject *pystring = PyUnicode_FromString("__dict__");
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
* */
- ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
- if (ret) return ret;
- else PyErr_Clear();
- /* done with subtypes */
-
- prop = RNA_struct_find_property(&self->ptr, name);
+ dict = PyObject_GenericGetAttr((PyObject *)self, pystring);
+ Py_DECREF(pystring);
- if (prop) {
- ret = pyrna_prop_to_py(&self->ptr, prop);
+ if (dict==NULL) {
+ PyErr_Clear();
+ ret = PyList_New(0);
+ }
+ else {
+ ret = PyDict_Keys(dict);
+ Py_DECREF(dict);
}
- else if (strcmp(name, "__dict__")==0) { /* Not quite correct, adding this so dir() gives good feedback */
+
+ /* Collect RNA items*/
+ {
PropertyRNA *iterprop, *nameprop;
CollectionPropertyIterator iter;
char name[256], *nameptr;
@@ -593,11 +597,13 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
iterprop= RNA_struct_iterator_property(&self->ptr);
RNA_property_collection_begin(&self->ptr, iterprop, &iter);
- ret = PyDict_New();
for(; iter.valid; RNA_property_collection_next(&iter)) {
if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
- PyDict_SetItemString(ret, nameptr, Py_None);
+
+ pystring = PyUnicode_FromString(nameptr);
+ PyList_Append(ret, pystring);
+ Py_DECREF(pystring);
if ((char *)&name != nameptr)
MEM_freeN(nameptr);
@@ -606,6 +612,31 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
RNA_property_collection_end(&iter);
}
+
+ return ret;
+}
+
+
+//---------------getattr--------------------------------------------
+static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
+{
+ char *name = _PyUnicode_AsString(pyname);
+ PyObject *ret;
+ PropertyRNA *prop;
+
+ /* Include this incase this instance is a subtype of a python class
+ * In these instances we may want to return a function or variable provided by the subtype
+ * */
+ ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
+ if (ret) return ret;
+ else PyErr_Clear();
+ /* done with subtypes */
+
+ prop = RNA_struct_find_property(&self->ptr, name);
+
+ if (prop) {
+ ret = pyrna_prop_to_py(&self->ptr, prop);
+ }
else {
PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name);
ret = NULL;
@@ -765,10 +796,10 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
return NULL;
}
-/*static struct PyMethodDef pyrna_struct_methods[] = {
+static struct PyMethodDef pyrna_struct_methods[] = {
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, ""},
{NULL, NULL, 0, NULL}
-};*/
+};
static struct PyMethodDef pyrna_prop_methods[] = {
{"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, ""},
@@ -875,7 +906,7 @@ PyTypeObject pyrna_struct_Type = {
NULL, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
+ pyrna_struct_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
NULL, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
@@ -990,12 +1021,32 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
{
BPy_StructRNA *pyrna;
- if (ptr->data==NULL) {
+ if (ptr->data==NULL && ptr->type==NULL) {
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);
+ pyrna = (BPy_StructRNA *) tp->tp_alloc(tp, 0);
+ }
+ else {
+ 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;
@@ -1029,15 +1080,7 @@ PyObject *BPY_rna_module( void )
{
PointerRNA ptr;
- if( PyType_Ready( &pyrna_struct_Type ) < 0 )
- return NULL;
-
- /* 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_prop_Type ) < 0 )
- return NULL;
+ /* types init moved to BPY_rna_init_types */
/* for now, return the base RNA type rather then a real module */
RNA_main_pointer_create(G.main, &ptr);
@@ -1058,4 +1101,203 @@ PyObject *BPY_rna_doc( void )
return pyrna_struct_CreatePyObject(&ptr);
}
+#ifdef PY_CLASS_SUBTYPE
+void BPY_rna_init_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;
+
+
+ /* 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();
+ }
+
+ newclass = PyObject_CallObject((PyObject *)&PyType_Type, args);
+
+ Py_DECREF(args);
+
+ BPy_RNA_PYTYPE(iter.ptr.data) = (void * )newclass;
+
+ // printf("BPyRNA_PyTypes: %s\n", tp_name);
+
+ if ((char *)&name != nameptr)
+ MEM_freeN(nameptr);
+ }
+ }
+ RNA_property_collection_end(&iter);
+}
+
+void BPY_rna_free_types(void) {};
+
+#else // Other method uses C defined PyTypes
+
+static void *tp_mem = NULL;
+void BPY_rna_init_types(void)
+{
+ PyTypeObject init_struct_type = pyrna_struct_Type; /* store this type to make copies from */
+
+ /* Now initialize new subtypes based on pyrna_struct_Type */
+ typedef struct PyTypeObject_Name {PyTypeObject tp; char name[64];} PyTypeObject_Name;
+ PyTypeObject_Name *tp_mem_ptr;
+ PyTypeObject *tp;
+ char *tp_name;
+ PointerRNA ptr;
+
+ CollectionPropertyIterator iter;
+ PropertyRNA *nameprop, *prop;
+ char name[256], *nameptr;
+
+
+ /* 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;
+
+ /* Note, making subtypes could be done by using an equivelent of
+ class MyClass(RNA_Struct)
+ */
+
+
+ /* 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");
+
+ tp_mem = tp_mem_ptr = MEM_mallocN(sizeof(PyTypeObject_Name) * RNA_property_collection_length(&ptr, prop), "BPyRNA_PyTypes");
+
+ 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))) {
+
+ nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
+
+ //tp = MEM_mallocN(sizeof(PyTypeObject_Name), "pyrna");
+ tp = &(tp_mem_ptr->tp);
+ tp_name = tp_mem_ptr->name;
+ snprintf(tp_name, 64, "BPyRNA_%s", nameptr);
+
+
+ *tp= init_struct_type; /* Copy the uninitialized pyrna_struct_Type */
+ tp->tp_name= tp_name;
+ tp->tp_base= &pyrna_struct_Type;
+
+ /* Todo - add special tp->tp_new function that lets us subtupe rna! */
+
+ if( PyType_Ready( tp ) < 0 ) {
+ printf("PyType_Ready failed\n");
+ }
+
+ BPy_RNA_PYTYPE(iter.ptr.data) = tp;
+
+ // printf("BPyRNA_PyTypes: %s\n", tp_name);
+
+ if ((char *)&name != nameptr)
+ MEM_freeN(nameptr);
+ }
+ tp_mem_ptr++;
+ }
+ RNA_property_collection_end(&iter);
+}
+
+/* Runs after python is finished, dont use any python functions */
+void BPY_rna_free_types(void)
+{
+ if (tp_mem==NULL)
+ return;
+
+ /* We dont really have to clear each structs type but may want to, also might allocate each type on its own */
+#if 0
+ PointerRNA ptr;
+
+ CollectionPropertyIterator iter;
+ PropertyRNA *prop;
+
+ /* 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) {
+ if (BPy_RNA_PYTYPE(iter.ptr.data)) {
+ /*
+ PyTypeObject *tp = BPy_RNA_PYTYPE(iter.ptr.data);
+ printf("BPyRNA clear: %s %d\n", tp->tp_name, (int)(long)BPy_RNA_PYTYPE(iter.ptr.data));
+ */
+
+ /* May want to alloc each type on its own however this makes it hard to know if RNA subtypes are using the type */
+
+ /* PyMem_Free( BPy_RNA_PYTYPE(iter.ptr.data) );
+ MEM_freeN( BPy_RNA_PYTYPE(iter.ptr.data) ); */
+ BPy_RNA_PYTYPE(iter.ptr.data)= NULL;
+ }
+ }
+ }
+ RNA_property_collection_end(&iter);
+#endif
+
+ MEM_freeN( tp_mem );
+ tp_mem = NULL;
+}
+#endif // END PYTYPE COPY METHOD
+
+
+
+
+
+
+
+
+
+
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index fc16ad6ea9a..63a2be9a31a 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -36,6 +36,17 @@ extern PyTypeObject pyrna_prop_Type;
#define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type))
#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
+ //XXX add propper accessor function, we know this is just after next/prev pointers
+
+ #define BPy_RNA_PYTYPE( _data ) (((BPy_StructFakeType *)(_data))->py_type)
+
+typedef struct {
+ void * _a;
+ void * _b;
+ PyTypeObject *py_type;
+} BPy_StructFakeType;
+
+
typedef struct {
PyObject_HEAD /* required python macro */
PointerRNA ptr;
@@ -50,6 +61,9 @@ typedef struct {
PyObject *BPY_rna_module( void );
PyObject *BPY_rna_doc( void );
+void BPY_rna_init_types( void );
+void BPY_rna_free_types( void );
+
PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr );
PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop );
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index 8bdb6334a91..724c99098f4 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -163,7 +163,7 @@ void PyObSpit(char *name, PyObject *var) {
}
void PyLineSpit(void) {
- char filename[512];
+ char *filename;
int lineno;
PyErr_Clear();
diff --git a/source/blender/python/rna_dump.py b/source/blender/python/rna_dump.py
new file mode 100644
index 00000000000..826051d9ceb
--- /dev/null
+++ b/source/blender/python/rna_dump.py
@@ -0,0 +1,112 @@
+ # ***** BEGIN GPL LICENSE BLOCK *****
+ #
+ # This program is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU General Public License
+ # as published by the Free Software Foundation; either version 2
+ # of the License, or (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software Foundation,
+ # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ #
+ # Contributor(s): Campbell Barton
+ #
+ # #**** END GPL LICENSE BLOCK #****
+
+
+PRINT_DATA = True
+VERBOSE = False
+VERBOSE_TYPE = False
+SKIP_RECURSIVE = False
+
+
+def seek(r, txt):
+ print(txt)
+ newtxt = ''
+
+ if len(txt) > 200:
+ print ("Somthing is wrong")
+ print (txt)
+ return
+
+ type_r = type(r)
+
+ # print(type_r)
+ # print(dir(r))
+
+ # basic types
+ if type_r in (float, int, bool, type(None)):
+ if PRINT_DATA:
+ print(txt + ' -> ' + str(r))
+ return
+
+ if type_r == str:
+ if PRINT_DATA:
+ print(txt + ' -> "' + str(r) + '"')
+ return
+
+ try: keys = r.keys()
+ except: keys = None
+
+ if keys != None:
+ if PRINT_DATA:
+ print(txt + '.keys() - ' + str(r.keys()))
+
+ try: __members__ = dir(r)
+ except: __members__ = []
+
+ for item in __members__:
+ if item.startswith('__'):
+ continue
+
+ if PRINT_DATA: newtxt = txt + '.' + item
+
+ if item == 'rna_type' and VERBOSE_TYPE==False: # just avoid because it spits out loads of data
+ continue
+
+ if SKIP_RECURSIVE:
+ if item in txt:
+ if PRINT_DATA:
+ print(newtxt + ' - (skipping to avoid recursive search)')
+ continue
+
+ try: value = getattr(r, item)
+ except: value = None
+
+ seek( value, newtxt)
+
+
+ if keys:
+ for k in keys:
+ if PRINT_DATA: newtxt = txt + '["' + k + '"]'
+ seek(r.__getitem__(k), newtxt)
+
+ else:
+ try: length = len( r )
+ except: length = 0
+
+ if VERBOSE==False and length >= 4:
+ for i in (0, length-1):
+ if i>0:
+ if PRINT_DATA:
+ print((' '*len(txt)) + ' ... skipping '+str(length-2)+' items ...')
+
+ if PRINT_DATA: newtxt = txt + '[' + str(i) + ']'
+ seek(r[i], newtxt)
+ else:
+ for i in range(length):
+ if PRINT_DATA: newtxt = txt + '[' + str(i) + ']'
+ seek(r[i], newtxt)
+
+#print (dir(bpy))
+seek(bpy, 'bpy')
+
+
+#print dir(bpy)
+#import sys
+#sys.exit()
diff --git a/source/blender/python/simple_enum_gen.py b/source/blender/python/simple_enum_gen.py
new file mode 100644
index 00000000000..ad9dc3053d8
--- /dev/null
+++ b/source/blender/python/simple_enum_gen.py
@@ -0,0 +1,65 @@
+ # ***** BEGIN GPL LICENSE BLOCK *****
+ #
+ # This program is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU General Public License
+ # as published by the Free Software Foundation; either version 2
+ # of the License, or (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software Foundation,
+ # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ #
+ # Contributor(s): Campbell Barton
+ #
+ # #**** END GPL LICENSE BLOCK #****
+
+defs = """
+ SPACE_EMPTY,
+ SPACE_VIEW3D,
+ SPACE_IPO,
+ SPACE_OOPS,
+ SPACE_BUTS,
+ SPACE_FILE,
+ SPACE_IMAGE,
+ SPACE_INFO,
+ SPACE_SEQ,
+ SPACE_TEXT,
+ SPACE_IMASEL,
+ SPACE_SOUND,
+ SPACE_ACTION,
+ SPACE_NLA,
+ SPACE_SCRIPT,
+ SPACE_TIME,
+ SPACE_NODE,
+ SPACEICONMAX
+"""
+
+print '\tmod = PyModule_New("dummy");'
+print '\tPyModule_AddObject( submodule, "key", mod );'
+
+for d in defs.split('\n'):
+
+ d = d.replace(',', ' ')
+ w = d.split()
+
+ if not w:
+ continue
+
+ try: w.remove("#define")
+ except: pass
+
+ # print w
+
+ val = w[0]
+ py_val = w[0]
+
+ print '\tPyModule_AddObject( mod, "%s", PyLong_FromSize_t(%s) );' % (val, py_val)
+
+
+
+