diff options
Diffstat (limited to 'source/blender/python')
-rw-r--r-- | source/blender/python/epy_doc_gen.py | 103 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_operator.c | 38 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 19 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.h | 2 |
4 files changed, 151 insertions, 11 deletions
diff --git a/source/blender/python/epy_doc_gen.py b/source/blender/python/epy_doc_gen.py index 6808a691e20..01c4f20962d 100644 --- a/source/blender/python/epy_doc_gen.py +++ b/source/blender/python/epy_doc_gen.py @@ -27,17 +27,17 @@ # # if you dont have graphvis installed ommit the --graph arg. - +def range_str(val): + if val < -10000000: return '-inf' + if val > 10000000: return 'inf' + if type(val)==float: + return '%g' % val + else: + return str(val) def rna2epy(target_path): - def range_str(val): - if val < -10000000: return '-inf' - if val > 10000000: return 'inf' - if type(val)==float: - return '%g' % val - else: - return str(val) + def write_struct(rna_struct): identifier = rna_struct.identifier @@ -155,6 +155,93 @@ def rna2epy(target_path): # # We could also just run.... # os.system('epydoc source/blender/python/doc/rna.py -o ./source/blender/python/doc/html -v') +def op2epy(target_path): + out = open(target_path, 'w') + + operators = bpyoperator.__members__ + operators.remove('add') + operators.remove('remove') + operators.sort() + + + for op in operators: + + + # Keyword attributes + kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'" + kw_arg_attrs = [] # "@type mode: int" + + rna = getattr(bpyoperator, op).rna + rna_struct = rna.rna_type + # print (op_rna.__members__) + for rna_prop_identifier, rna_prop in rna_struct.properties.items(): + if rna_prop_identifier=='rna_type': + continue + # ['rna_type', 'name', 'array_length', 'description', 'hard_max', 'hard_min', 'identifier', 'precision', 'readonly', 'soft_max', 'soft_min', 'step', 'subtype', 'type'] + #rna_prop= op_rna.rna_type.properties[attr] + rna_prop_type = rna_prop.type.lower() # enum, float, int, boolean + + try: + val = getattr(rna, rna_prop_identifier) + except: + val = '<UNDEFINED>' + + kw_type_str= "@type %s: %s" % (rna_prop_identifier, rna_prop_type) + kw_param_str= "@param %s: %s" % (rna_prop_identifier, rna_prop.description) + kw_param_set = False + + if rna_prop_type=='float': + val_str= '%g' % val + if '.' not in val_str: + val_str += '.0' + kw_param_str += (' in (%s, %s)' % (range_str(rna_prop.hard_min), range_str(rna_prop.hard_max))) + kw_param_set= True + + elif rna_prop_type=='int': + val_str='%d' % val + # print (rna_prop.__members__) + kw_param_str += (' in (%s, %s)' % (range_str(rna_prop.hard_min), range_str(rna_prop.hard_max))) + # These strings dont have a max length??? + #kw_param_str += ' (maximum length of %s)' % (rna_prop.max_length) + kw_param_set= True + + elif rna_prop_type=='boolean': + if val: val_str='True' + else: val_str='False' + + elif rna_prop_type=='enum': + val_str="'%s'" % val + kw_param_str += (' in (%s)' % ', '.join(rna_prop.items.keys())) + kw_param_set= True + + elif rna_prop_type=='string': + val_str='"%s"' % val + + # todo - collection - array + # print (rna_prop.type) + + kw_args.append('%s = %s' % (rna_prop_identifier, val_str)) + + # stora + + kw_arg_attrs.append(kw_type_str) + if kw_param_set: + kw_arg_attrs.append(kw_param_str) + + + + out.write('def %s(%s):\n' % (op, ', '.join(kw_args))) + out.write('\t"""\n') + for desc in kw_arg_attrs: + out.write('\t%s\n' % desc) + out.write('\t@rtype: None\n') + out.write('\t"""\n') + + + out.write('\n') + out.close() + if __name__ == '__main__': rna2epy('source/blender/python/doc/rna.py') + op2epy('source/blender/python/doc/bpyoperator.py') diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 2765a59ce42..1babaebdab8 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -167,6 +167,42 @@ static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname ) return ret; } +//---------------getattr-------------------------------------------- +static PyObject * pyop_func_getattro(BPy_OperatorFunc * self, PyObject *pyname) +{ + char *name = _PyUnicode_AsString(pyname); + PyObject *ret; + + if( strcmp( name, "__members__" ) == 0 ) { + ret = PyList_New(1); + PyList_SET_ITEM(ret, 0, PyUnicode_FromString("rna")); + } + else if ( strcmp( name, "rna" ) == 0 ) { + BPy_StructRNA *pyrna; + PointerRNA ptr; + //IDProperty *properties = NULL; + wmOperatorType *ot; + + ot= WM_operatortype_find(self->name); + if (ot == NULL) { + PyErr_SetString( PyExc_SystemError, "Operator could not be found"); + 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, NULL, ot->srna, &pyrna->properties, &pyrna->ptr); + ret= (PyObject *)pyrna; + } + else { + PyErr_Format( PyExc_AttributeError, "Operator \"%s\" not found", name); + ret= NULL; + } + + return ret; +} + static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObject *kw) { IDProperty *properties = NULL; @@ -338,7 +374,7 @@ PyTypeObject pyop_func_Type = { NULL, /* hashfunc tp_hash; */ (ternaryfunc)pyop_func_call, /* ternaryfunc tp_call; */ NULL, /* reprfunc tp_str; */ - NULL, /*PyObject_GenericGetAttr - MINGW Complains, assign later */ /* getattrofunc tp_getattro; */ + ( getattrofunc ) pyop_func_getattro, /* getattrofunc tp_getattro; */ NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */ /* setattrofunc tp_setattro; */ /* Functions to access object as input/output buffer */ diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 994d67a5201..d761354f23b 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -59,6 +59,20 @@ static long pyrna_struct_hash( BPy_StructRNA * self ) return (long)self->ptr.data; } +/* use our own dealloc so we can free a property if we use one */ +static void pyrna_struct_dealloc( BPy_StructRNA * self ) +{ + /* Note!! for some weired reason calling PyObject_DEL() directly crashes blender! */ + if (self->properties) { + IDP_FreeProperty(self->properties); + MEM_freeN(self->properties); + self->properties= NULL; + } + + ((PyObject *)self)->ob_type->tp_free(self); + return; +} + static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) { const EnumPropertyItem *item; @@ -940,7 +954,7 @@ PyTypeObject pyrna_struct_Type = { sizeof( BPy_StructRNA ), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - NULL, /* tp_dealloc */ + ( destructor ) pyrna_struct_dealloc,/* tp_dealloc */ NULL, /* printfunc tp_print; */ NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ @@ -1110,7 +1124,8 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr ) return NULL; } - pyrna->ptr = *ptr; + pyrna->ptr= *ptr; + pyrna->properties= NULL; return ( PyObject * ) pyrna; } diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 2cf4a57f76d..8f21e6d80c8 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -28,6 +28,7 @@ #include "RNA_access.h" #include "RNA_types.h" +#include "BKE_idprop.h" extern PyTypeObject pyrna_struct_Type; extern PyTypeObject pyrna_prop_Type; @@ -35,6 +36,7 @@ extern PyTypeObject pyrna_prop_Type; typedef struct { PyObject_VAR_HEAD /* required python macro */ PointerRNA ptr; + IDProperty *properties; /* needed in some cases for RNA_pointer_create(), free when deallocing */ } BPy_StructRNA; typedef struct { |