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)
This commit is contained in:
@@ -121,12 +121,19 @@ def rna2epy(target_path):
|
||||
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
|
||||
@@ -178,7 +185,7 @@ def rna2epy(target_path):
|
||||
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 @@ def op2epy(target_path):
|
||||
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))
|
||||
|
||||
@@ -34,30 +34,23 @@ void BPY_free_compiled_text( struct Text *text )
|
||||
|
||||
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);
|
||||
|
||||
|
||||
// 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);
|
||||
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 - evil, need to access context
|
||||
item = PyCObject_FromVoidPtr( C, NULL );
|
||||
@@ -80,8 +73,6 @@ void BPY_start_python( void )
|
||||
|
||||
// todo - sys paths - our own imports
|
||||
|
||||
BPY_rna_init_types();
|
||||
|
||||
py_tstate = PyGILState_GetThisThreadState();
|
||||
PyEval_ReleaseThread(py_tstate);
|
||||
|
||||
@@ -96,7 +87,6 @@ void BPY_end_python( void )
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 @@ PyTypeObject pyrna_prop_Type = {
|
||||
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 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
|
||||
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 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
|
||||
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 @@ PyObject *BPY_rna_module( void )
|
||||
{
|
||||
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,167 +1156,20 @@ PyObject *BPY_rna_doc( void )
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
PyObject *mod, *dict, *type, *name;
|
||||
|
||||
mod = PyModule_New("types");
|
||||
dict = PyModule_GetDict(mod);
|
||||
|
||||
/* for now, return the base RNA type rather then a real module */
|
||||
RNA_blender_rna_pointer_create(&ptr);
|
||||
@@ -1269,35 +1178,26 @@ void BPY_rna_free_types(void)
|
||||
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;
|
||||
type = (PyObject *)BPy_RNA_PYTYPE(iter.ptr.data);
|
||||
if (type==NULL) {
|
||||
type = pyrna_struct_Subtype(&iter.ptr);
|
||||
}
|
||||
if (type) {
|
||||
name = PyObject_GetAttrString(type, "__name__"); /* myClass.__name__ */
|
||||
if (name) {
|
||||
PyDict_SetItem(dict, name, type);
|
||||
Py_DECREF(name);
|
||||
}
|
||||
else {
|
||||
printf("could not get type __name__\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("could not generate type\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
RNA_property_collection_end(&iter);
|
||||
#endif
|
||||
|
||||
MEM_freeN( tp_mem );
|
||||
tp_mem = NULL;
|
||||
|
||||
return mod;
|
||||
}
|
||||
#endif // END PYTYPE COPY METHOD
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -60,10 +60,8 @@ typedef struct {
|
||||
} BPy_PropertyRNA;
|
||||
|
||||
PyObject *BPY_rna_module( void );
|
||||
PyObject *BPY_rna_doc( void );
|
||||
void BPY_rna_init_types( void );
|
||||
void BPY_rna_free_types( void );
|
||||
|
||||
/*PyObject *BPY_rna_doc( void );*/
|
||||
PyObject *BPY_rna_types( void );
|
||||
|
||||
PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr );
|
||||
PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop );
|
||||
|
||||
@@ -104,7 +104,7 @@ def seek(r, txt):
|
||||
seek(r[i], newtxt)
|
||||
|
||||
#print (dir(bpy))
|
||||
seek(bpy, 'bpy')
|
||||
seek(bpy.data, 'bpy.data')
|
||||
|
||||
|
||||
#print dir(bpy)
|
||||
|
||||
Reference in New Issue
Block a user