diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/python/epy_doc_gen.py | 1302 | ||||
-rw-r--r-- | source/blender/python/rna_dump.py | 196 | ||||
-rw-r--r-- | source/blender/python/simple_enum_gen.py | 70 |
3 files changed, 784 insertions, 784 deletions
diff --git a/source/blender/python/epy_doc_gen.py b/source/blender/python/epy_doc_gen.py index 851eaa3b6f3..202a1df3502 100644 --- a/source/blender/python/epy_doc_gen.py +++ b/source/blender/python/epy_doc_gen.py @@ -21,17 +21,17 @@ script_help_msg = ''' Usage, run this script from blenders root path once you have compiled blender - ./blender.bin -P source/blender/python/epy_doc_gen.py + ./blender.bin -P source/blender/python/epy_doc_gen.py This will generate rna.py and bpyoperator.py in "./source/blender/python/doc/" Generate html docs by running... - epydoc source/blender/python/doc/*.py -v \\ - -o source/blender/python/doc/html \\ - --inheritance=included \\ - --no-sourcecode \\ - --graph=classtree \\ - --graph-font-size=8 + epydoc source/blender/python/doc/*.py -v \\ + -o source/blender/python/doc/html \\ + --inheritance=included \\ + --no-sourcecode \\ + --graph=classtree \\ + --graph-font-size=8 ''' @@ -47,689 +47,689 @@ INIT_SUBMODULES = {} # store initialized files INIT_SUBMODULES_IMPORTS = {} # dont import the same module twice def append_package(package_path, mod_name): - - init_path = os.path.join(os.path.dirname(package_path), "__init__.py") - - # avoid double ups - if mod_name: - imports = INIT_SUBMODULES_IMPORTS.setdefault(init_path, []) - if mod_name in imports: - return - imports.append(mod_name) - - try: - os.makedirs(os.path.dirname(init_path)) # make the dirs if they are not there - except: - pass - - # Open the new file for the first time, otherwise keep it open. - f = INIT_SUBMODULES.get(init_path) - if f == None: - f = INIT_SUBMODULES[init_path] = open(init_path, 'w') - - if mod_name: - f.write("import %s\n" % mod_name) - - return f + + init_path = os.path.join(os.path.dirname(package_path), "__init__.py") + + # avoid double ups + if mod_name: + imports = INIT_SUBMODULES_IMPORTS.setdefault(init_path, []) + if mod_name in imports: + return + imports.append(mod_name) + + try: + os.makedirs(os.path.dirname(init_path)) # make the dirs if they are not there + except: + pass + + # Open the new file for the first time, otherwise keep it open. + f = INIT_SUBMODULES.get(init_path) + if f == None: + f = INIT_SUBMODULES[init_path] = open(init_path, 'w') + + if mod_name: + f.write("import %s\n" % mod_name) + + return f def append_package_recursive(package_path, BASEPATH): - ''' - assume the last item of package_path will be a file (not a dir thats created) - ''' - - package_path = os.path.splitext(package_path)[0] # incase of .py - - try: - os.makedirs(os.path.join(BASEPATH, os.path.dirname(package_path))) # make the dirs if they are not there - except: - pass - - new_path = BASEPATH - - for mod_name in package_path.split(os.sep): - init_path = os.path.join(new_path, "__init__.py") - new_path = os.path.join(new_path, mod_name) - append_package(init_path, mod_name) + ''' + assume the last item of package_path will be a file (not a dir thats created) + ''' + + package_path = os.path.splitext(package_path)[0] # incase of .py + + try: + os.makedirs(os.path.join(BASEPATH, os.path.dirname(package_path))) # make the dirs if they are not there + except: + pass + + new_path = BASEPATH + + for mod_name in package_path.split(os.sep): + init_path = os.path.join(new_path, "__init__.py") + new_path = os.path.join(new_path, mod_name) + append_package(init_path, mod_name) def open_submodule(subpath, BASEPATH): - ''' - This is a utility function that lets us quickly add submodules - ''' - - # create all the package paths leading up to this module - append_package_recursive(subpath, BASEPATH) - - module_name = os.path.basename( os.path.splitext(subpath)[0] ) - mod_path = os.path.join(BASEPATH, subpath) - - # Open the new file for the first time, otherwise keep it open. - f = SUBMODULES.get(mod_path) - if f == None: - f = SUBMODULES[mod_path] = open(mod_path, 'w') - - f = open(mod_path, 'w') - return f + ''' + This is a utility function that lets us quickly add submodules + ''' + + # create all the package paths leading up to this module + append_package_recursive(subpath, BASEPATH) + + module_name = os.path.basename( os.path.splitext(subpath)[0] ) + mod_path = os.path.join(BASEPATH, subpath) + + # Open the new file for the first time, otherwise keep it open. + f = SUBMODULES.get(mod_path) + if f == None: + f = SUBMODULES[mod_path] = open(mod_path, 'w') + + f = open(mod_path, 'w') + return f def close_all(): - for files in (INIT_SUBMODULES.values(), SUBMODULES.values()): - for f in files: - if f.name.endswith('.py'): - f_name = f.name - f.close() - - f = open(f_name, 'a') - f.write("\ndel __package__\n") # annoying, no need do show this - - - f.close() + for files in (INIT_SUBMODULES.values(), SUBMODULES.values()): + for f in files: + if f.name.endswith('.py'): + f_name = f.name + f.close() + + f = open(f_name, 'a') + f.write("\ndel __package__\n") # annoying, no need do show this + + + f.close() 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) + if val < -10000000: return '-inf' + if val > 10000000: return 'inf' + if type(val)==float: + return '%g' % val + else: + return str(val) def get_array_str(length): - if length > 0: return ' array of %d items' % length - else: return '' + if length > 0: return ' array of %d items' % length + else: return '' def full_rna_struct_path(rna_struct): - ''' - Needed when referencing one struct from another - ''' - nested = rna_struct.nested - if nested: - return "%s.%s" % (full_rna_struct_path(nested), rna_struct.identifier) - else: - return rna_struct.identifier + ''' + Needed when referencing one struct from another + ''' + nested = rna_struct.nested + if nested: + return "%s.%s" % (full_rna_struct_path(nested), rna_struct.identifier) + else: + return rna_struct.identifier def rna_id_ignore(rna_id): - if rna_id == "rna_type": - return True - - if "_OT_" in rna_id: - return True - if "_MT_" in rna_id: - return True - if "_PT_" in rna_id: - return True - - return False + if rna_id == "rna_type": + return True + + if "_OT_" in rna_id: + return True + if "_MT_" in rna_id: + return True + if "_PT_" in rna_id: + return True + + return False def write_func(rna, ident, out, func_type): - # Keyword attributes - kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'" - kw_arg_attrs = [] # "@type mode: int" - - rna_struct= rna.rna_type - - # Operators and functions work differently - if func_type=='OPERATOR': - rna_func_name = rna_struct.identifier.split("_OT_")[-1] - rna_func_desc = rna_struct.description.strip() - items = rna_struct.properties.items() - else: - rna_func_name = rna.identifier - rna_func_desc = rna.description.strip() - items = rna.parameters.items() - - - for rna_prop_identifier, rna_prop in items: - if rna_id_ignore(rna_prop_identifier): - continue - - # clear vars - val = val_error = val_str = rna_prop_type = None - - # ['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 - - - # only for rna functions, operators should not get pointers as args - if rna_prop_type=='pointer': - rna_prop_type_refine = "L{%s}" % rna_prop.fixed_type.identifier - else: - rna_prop_type_refine = rna_prop_type - - - try: length = rna_prop.array_length - except: length = 0 - - array_str = get_array_str(length) - - if rna_prop.use_return: - kw_type_str= "@rtype: %s%s" % (rna_prop_type_refine, array_str) - kw_param_str= "@return: %s" % (rna_prop.description.strip()) - else: - kw_type_str= "@type %s: %s%s" % (rna_prop_identifier, rna_prop_type_refine, array_str) - kw_param_str= "@param %s: %s" % (rna_prop_identifier, rna_prop.description.strip()) - - kw_param_set = False - - if func_type=='OPERATOR': - try: - val = getattr(rna, rna_prop_identifier) - val_error = False - except: - val = "'<UNDEFINED>'" - val_error = True - - - if val_error: - val_str = val - elif rna_prop_type=='float': - if length==0: - val_str= '%g' % val - if '.' not in val_str and '-' not in val_str: # value could be 1e-05 - val_str += '.0' - else: - # array - val_str = str(tuple(val)) - - 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': - if length==0: - val_str='%d' % val - else: - val_str = str(tuple(val)) - - # print(dir(rna_prop)) - 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 length==0: - if val: val_str='True' - else: val_str='False' - else: - val_str = str(tuple(val)) - - elif rna_prop_type=='enum': - # no array here? - val_str="'%s'" % val - # Too cramped - kw_param_str += (' in (%s)' % ', '.join(rna_prop.items.keys())) - - kw_param_set= True - - elif rna_prop_type=='string': - # no array here? - val_str='"%s"' % val - - # todo - collection - array - # print (rna_prop.type) - - kw_args.append('%s = %s' % (rna_prop_identifier, val_str)) - - # stora - else: - # currently functions dont have a default value - if not rna_prop.use_return: - kw_args.append('%s' % (rna_prop_identifier)) - else: - kw_param_set = True - - - # Same for operators and functions - kw_arg_attrs.append(kw_type_str) - if kw_param_set: - kw_arg_attrs.append(kw_param_str) - - - - out.write(ident+'def %s(%s):\n' % (rna_func_name, ', '.join(kw_args))) - out.write(ident+'\t"""\n') - out.write(ident+'\t%s\n' % rna_func_desc) - for desc in kw_arg_attrs: - out.write(ident+'\t%s\n' % desc) - - # out.write(ident+'\t@rtype: None\n') # implicit - out.write(ident+'\t"""\n') - + # Keyword attributes + kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'" + kw_arg_attrs = [] # "@type mode: int" + + rna_struct= rna.rna_type + + # Operators and functions work differently + if func_type=='OPERATOR': + rna_func_name = rna_struct.identifier.split("_OT_")[-1] + rna_func_desc = rna_struct.description.strip() + items = rna_struct.properties.items() + else: + rna_func_name = rna.identifier + rna_func_desc = rna.description.strip() + items = rna.parameters.items() + + + for rna_prop_identifier, rna_prop in items: + if rna_id_ignore(rna_prop_identifier): + continue + + # clear vars + val = val_error = val_str = rna_prop_type = None + + # ['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 + + + # only for rna functions, operators should not get pointers as args + if rna_prop_type=='pointer': + rna_prop_type_refine = "L{%s}" % rna_prop.fixed_type.identifier + else: + rna_prop_type_refine = rna_prop_type + + + try: length = rna_prop.array_length + except: length = 0 + + array_str = get_array_str(length) + + if rna_prop.use_return: + kw_type_str= "@rtype: %s%s" % (rna_prop_type_refine, array_str) + kw_param_str= "@return: %s" % (rna_prop.description.strip()) + else: + kw_type_str= "@type %s: %s%s" % (rna_prop_identifier, rna_prop_type_refine, array_str) + kw_param_str= "@param %s: %s" % (rna_prop_identifier, rna_prop.description.strip()) + + kw_param_set = False + + if func_type=='OPERATOR': + try: + val = getattr(rna, rna_prop_identifier) + val_error = False + except: + val = "'<UNDEFINED>'" + val_error = True + + + if val_error: + val_str = val + elif rna_prop_type=='float': + if length==0: + val_str= '%g' % val + if '.' not in val_str and '-' not in val_str: # value could be 1e-05 + val_str += '.0' + else: + # array + val_str = str(tuple(val)) + + 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': + if length==0: + val_str='%d' % val + else: + val_str = str(tuple(val)) + + # print(dir(rna_prop)) + 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 length==0: + if val: val_str='True' + else: val_str='False' + else: + val_str = str(tuple(val)) + + elif rna_prop_type=='enum': + # no array here? + val_str="'%s'" % val + # Too cramped + kw_param_str += (' in (%s)' % ', '.join(rna_prop.items.keys())) + + kw_param_set= True + + elif rna_prop_type=='string': + # no array here? + val_str='"%s"' % val + + # todo - collection - array + # print (rna_prop.type) + + kw_args.append('%s = %s' % (rna_prop_identifier, val_str)) + + # stora + else: + # currently functions dont have a default value + if not rna_prop.use_return: + kw_args.append('%s' % (rna_prop_identifier)) + else: + kw_param_set = True + + + # Same for operators and functions + kw_arg_attrs.append(kw_type_str) + if kw_param_set: + kw_arg_attrs.append(kw_param_str) + + + + out.write(ident+'def %s(%s):\n' % (rna_func_name, ', '.join(kw_args))) + out.write(ident+'\t"""\n') + out.write(ident+'\t%s\n' % rna_func_desc) + for desc in kw_arg_attrs: + out.write(ident+'\t%s\n' % desc) + + # out.write(ident+'\t@rtype: None\n') # implicit + out.write(ident+'\t"""\n') + def rna2epy(BASEPATH): - - # Use for faster lookups - # use rna_struct.identifier as the key for each dict - rna_struct_dict = {} # store identifier:rna lookups - rna_full_path_dict = {} # store the result of full_rna_struct_path(rna_struct) - rna_children_dict = {} # store all rna_structs nested from here - rna_references_dict = {} # store a list of rna path strings that reference this type - rna_functions_dict = {} # store all functions directly in this type (not inherited) - rna_words = set() - - # def write_func(rna_func, ident): - - - def write_struct(rna_struct, ident): - identifier = rna_struct.identifier - - rna_base = rna_struct.base - - if rna_base: - out.write(ident+ 'class %s(%s):\n' % (identifier, rna_base.identifier)) - rna_base_prop_keys = rna_base.properties.keys() # could be cached - rna_base_func_keys = [f.identifier for f in rna_base.functions] - else: - out.write(ident+ 'class %s:\n' % identifier) - rna_base_prop_keys = [] - rna_base_func_keys = [] - - out.write(ident+ '\t"""\n') - - title = 'The %s Object' % rna_struct.name - description = rna_struct.description.strip() - out.write(ident+ '\t%s\n' % title) - out.write(ident+ '\t%s\n' % ('=' * len(title))) - out.write(ident+ '\t\t%s\n' % description) - rna_words.update(description.split()) - - - # For convenience, give a list of all places were used. - rna_refs= rna_references_dict[identifier] - - if rna_refs: - out.write(ident+ '\t\t\n') - out.write(ident+ '\t\tReferences\n') - out.write(ident+ '\t\t==========\n') - - for rna_ref_string in rna_refs: - out.write(ident+ '\t\t\t- L{%s}\n' % rna_ref_string) - - out.write(ident+ '\t\t\n') - - else: - out.write(ident+ '\t\t\n') - out.write(ident+ '\t\t(no references to this struct found)\n') - out.write(ident+ '\t\t\n') - - for rna_prop_identifier, rna_prop in rna_struct.properties.items(): - - if rna_prop_identifier=='RNA': continue - if rna_id_ignore(rna_prop_identifier): continue - if rna_prop_identifier in rna_base_prop_keys: continue # does this prop exist in our parent class, if so skip - - rna_desc = rna_prop.description.strip() - - if rna_desc: rna_words.update(rna_desc.split()) - if not rna_desc: rna_desc = rna_prop.name - if not rna_desc: rna_desc = 'Note - No documentation for this property!' - - rna_prop_type = rna_prop.type.lower() - - if rna_prop_type=='collection': collection_str = 'Collection of ' - else: collection_str = '' - - try: rna_prop_ptr = rna_prop.fixed_type - except: rna_prop_ptr = None - - try: length = rna_prop.array_length - except: length = 0 - - array_str = get_array_str(length) - - if rna_prop.editable: readonly_str = '' - else: readonly_str = ' (readonly)' - - if rna_prop_ptr: # Use the pointer type - out.write(ident+ '\t@ivar %s: %s\n' % (rna_prop_identifier, rna_desc)) - out.write(ident+ '\t@type %s: %sL{%s}%s%s\n' % (rna_prop_identifier, collection_str, rna_prop_ptr.identifier, array_str, readonly_str)) - else: - if rna_prop_type == 'enum': - if 0: - out.write(ident+ '\t@ivar %s: %s in (%s)\n' % (rna_prop_identifier, rna_desc, ', '.join(rna_prop.items.keys()))) - else: - out.write(ident+ '\t@ivar %s: %s in...\n' % (rna_prop_identifier, rna_desc)) - for e, e_rna_prop in rna_prop.items.items(): - #out.write(ident+ '\t\t- %s: %s\n' % (e, e_rna_prop.description)) # XXX - segfaults, FIXME - out.write(ident+ '\t\t- %s\n' % e) - - out.write(ident+ '\t@type %s: %s%s%s\n' % (rna_prop_identifier, rna_prop_type, array_str, readonly_str)) - elif rna_prop_type == 'int' or rna_prop_type == 'float': - out.write(ident+ '\t@ivar %s: %s\n' % (rna_prop_identifier, rna_desc)) - out.write(ident+ '\t@type %s: %s%s%s in [%s, %s]\n' % (rna_prop_identifier, rna_prop_type, array_str, readonly_str, range_str(rna_prop.hard_min), range_str(rna_prop.hard_max) )) - elif rna_prop_type == 'string': - out.write(ident+ '\t@ivar %s: %s (maximum length of %s)\n' % (rna_prop_identifier, rna_desc, rna_prop.max_length)) - out.write(ident+ '\t@type %s: %s%s%s\n' % (rna_prop_identifier, rna_prop_type, array_str, readonly_str)) - else: - out.write(ident+ '\t@ivar %s: %s\n' % (rna_prop_identifier, rna_desc)) - out.write(ident+ '\t@type %s: %s%s%s\n' % (rna_prop_identifier, rna_prop_type, array_str, readonly_str)) - - - out.write(ident+ '\t"""\n\n') - - - # Write functions - # for rna_func in rna_struct.functions: # Better ignore inherited (line below) - for rna_func in rna_functions_dict[identifier]: - if rna_func not in rna_base_func_keys: - write_func(rna_func, ident+'\t', out, 'FUNCTION') - - out.write('\n') - - # Now write children recursively - for child in rna_children_dict[identifier]: - write_struct(child, ident + '\t') - - - - # out = open(target_path, 'w') - out = open_submodule("types.py", BASEPATH) # bpy.types - - def base_id(rna_struct): - try: return rna_struct.base.identifier - except: return '' # invalid id - - #structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()] - ''' - structs = [] - 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) - - try: rna_struct = rna_type.bl_rna - except: rna_struct = None - - if rna_struct: - #if not rna_type_name.startswith('__'): - - identifier = rna_struct.identifier - - if not rna_id_ignore(identifier): - structs.append( (base_id(rna_struct), identifier, rna_struct) ) - - # Simple lookup - rna_struct_dict[identifier] = rna_struct - - # Store full rna path 'GameObjectSettings' -> 'Object.GameObjectSettings' - rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct) - - # Store a list of functions, remove inherited later - rna_functions_dict[identifier]= list(rna_struct.functions) - - - # fill in these later - rna_children_dict[identifier]= [] - rna_references_dict[identifier]= [] - - - else: - print("Ignoring", rna_type_name) - - - # Sucks but we need to copy this so we can check original parent functions - rna_functions_dict__copy = {} - for key, val in rna_functions_dict.items(): - rna_functions_dict__copy[key] = val[:] - - - 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 - deps_ok = False - while deps_ok == False: - deps_ok = True - rna_done = set() - - for i, (rna_base, identifier, rna_struct) in enumerate(structs): - - rna_done.add(identifier) - - if rna_base and rna_base not in rna_done: - deps_ok = False - data = structs.pop(i) - ok = False - while i < len(structs): - if structs[i][1]==rna_base: - structs.insert(i+1, data) # insert after the item we depend on. - ok = True - break - i+=1 - - if not ok: - print('Dependancy "%s" could not be found for "%s"' % (identifier, rna_base)) - - break - - # Done ordering structs - - - # precalc vars to avoid a lot of looping - for (rna_base, identifier, rna_struct) in structs: - - if rna_base: - rna_base_prop_keys = rna_struct_dict[rna_base].properties.keys() # could cache - rna_base_func_keys = [f.identifier for f in rna_struct_dict[rna_base].functions] - else: - rna_base_prop_keys = [] - rna_base_func_keys= [] - - # rna_struct_path = full_rna_struct_path(rna_struct) - rna_struct_path = rna_full_path_dict[identifier] - - for rna_prop_identifier, rna_prop in rna_struct.properties.items(): - - if rna_prop_identifier=='RNA': continue - if rna_id_ignore(rna_prop_identifier): continue - if rna_prop_identifier in rna_base_prop_keys: continue - - try: rna_prop_ptr = rna_prop.fixed_type - except: rna_prop_ptr = None - - # Does this property point to me? - if rna_prop_ptr: - rna_references_dict[rna_prop_ptr.identifier].append( "%s.%s" % (rna_struct_path, rna_prop_identifier) ) - - for rna_func in rna_struct.functions: - for rna_prop_identifier, rna_prop in rna_func.parameters.items(): - - if rna_prop_identifier=='RNA': continue - if rna_id_ignore(rna_prop_identifier): continue - if rna_prop_identifier in rna_base_func_keys: continue - - - try: rna_prop_ptr = rna_prop.fixed_type - except: rna_prop_ptr = None - - # Does this property point to me? - if rna_prop_ptr: - rna_references_dict[rna_prop_ptr.identifier].append( "%s.%s" % (rna_struct_path, rna_func.identifier) ) - - - # Store nested children - nested = rna_struct.nested - if nested: - rna_children_dict[nested.identifier].append(rna_struct) - - - if rna_base: - rna_funcs = rna_functions_dict[identifier] - if rna_funcs: - # Remove inherited functions if we have any - rna_base_funcs = rna_functions_dict__copy[rna_base] - rna_funcs[:] = [f for f in rna_funcs if f not in rna_base_funcs] - - rna_functions_dict__copy.clear() - del rna_functions_dict__copy - - # Sort the refs, just reads nicer - for rna_refs in rna_references_dict.values(): - rna_refs.sort() - - for (rna_base, identifier, rna_struct) in structs: - if rna_struct.nested: - continue - - write_struct(rna_struct, '') - - - out.write('\n') - out.close() - - # # We could also just run.... - # os.system('epydoc source/blender/python/doc/rna.py -o ./source/blender/python/doc/html -v') - - target_path = os.path.join(BASEPATH, "dump.py") # XXX - used for other funcs - - # Write graphviz - out= open(target_path.replace('.py', '.dot'), 'w') - out.write('digraph "rna data api" {\n') - out.write('\tnode [style=filled, shape = "box"];\n') - out.write('\toverlap=false;\n') - out.write('\trankdir = LR;\n') - out.write('\tsplines=true;\n') - out.write('\tratio=auto;\n') - - - - out.write('\tsize="10,10"\n') - #out.write('\tpage="8.5,11"\n') - #out.write('\tcenter=""\n') - - def isop(rna_struct): - return '_OT_' in rna_struct.identifier - - - for (rna_base, identifier, rna_struct) in structs: - if isop(rna_struct): - continue - - base = rna_struct.base - - - out.write('\t"%s";\n' % identifier) - - for (rna_base, identifier, rna_struct) in structs: - - if isop(rna_struct): - continue - - base = rna_struct.base - - if base and not isop(base): - out.write('\t"%s" -> "%s" [label="(base)" weight=1.0];\n' % (base.identifier, identifier)) - - nested = rna_struct.nested - if nested and not isop(nested): - out.write('\t"%s" -> "%s" [label="(nested)" weight=1.0];\n' % (nested.identifier, identifier)) - - - - rna_refs= rna_references_dict[identifier] - - for rna_ref_string in rna_refs: - - if '_OT_' in rna_ref_string: - continue - - ref = rna_ref_string.split('.')[-2] - out.write('\t"%s" -> "%s" [label="%s" weight=0.01];\n' % (ref, identifier, rna_ref_string)) - - - out.write('}\n') - out.close() - - # # We could also just run.... - # os.system('dot source/blender/python/doc/rna.dot -Tsvg -o ./source/blender/python/doc/rna.svg') - - - out= open(target_path.replace('.py', '.words'), 'w') - rna_words = list(rna_words) - rna_words.sort() - for w in rna_words: - out.write('%s\n' % w) - + + # Use for faster lookups + # use rna_struct.identifier as the key for each dict + rna_struct_dict = {} # store identifier:rna lookups + rna_full_path_dict = {} # store the result of full_rna_struct_path(rna_struct) + rna_children_dict = {} # store all rna_structs nested from here + rna_references_dict = {} # store a list of rna path strings that reference this type + rna_functions_dict = {} # store all functions directly in this type (not inherited) + rna_words = set() + + # def write_func(rna_func, ident): + + + def write_struct(rna_struct, ident): + identifier = rna_struct.identifier + + rna_base = rna_struct.base + + if rna_base: + out.write(ident+ 'class %s(%s):\n' % (identifier, rna_base.identifier)) + rna_base_prop_keys = rna_base.properties.keys() # could be cached + rna_base_func_keys = [f.identifier for f in rna_base.functions] + else: + out.write(ident+ 'class %s:\n' % identifier) + rna_base_prop_keys = [] + rna_base_func_keys = [] + + out.write(ident+ '\t"""\n') + + title = 'The %s Object' % rna_struct.name + description = rna_struct.description.strip() + out.write(ident+ '\t%s\n' % title) + out.write(ident+ '\t%s\n' % ('=' * len(title))) + out.write(ident+ '\t\t%s\n' % description) + rna_words.update(description.split()) + + + # For convenience, give a list of all places were used. + rna_refs= rna_references_dict[identifier] + + if rna_refs: + out.write(ident+ '\t\t\n') + out.write(ident+ '\t\tReferences\n') + out.write(ident+ '\t\t==========\n') + + for rna_ref_string in rna_refs: + out.write(ident+ '\t\t\t- L{%s}\n' % rna_ref_string) + + out.write(ident+ '\t\t\n') + + else: + out.write(ident+ '\t\t\n') + out.write(ident+ '\t\t(no references to this struct found)\n') + out.write(ident+ '\t\t\n') + + for rna_prop_identifier, rna_prop in rna_struct.properties.items(): + + if rna_prop_identifier=='RNA': continue + if rna_id_ignore(rna_prop_identifier): continue + if rna_prop_identifier in rna_base_prop_keys: continue # does this prop exist in our parent class, if so skip + + rna_desc = rna_prop.description.strip() + + if rna_desc: rna_words.update(rna_desc.split()) + if not rna_desc: rna_desc = rna_prop.name + if not rna_desc: rna_desc = 'Note - No documentation for this property!' + + rna_prop_type = rna_prop.type.lower() + + if rna_prop_type=='collection': collection_str = 'Collection of ' + else: collection_str = '' + + try: rna_prop_ptr = rna_prop.fixed_type + except: rna_prop_ptr = None + + try: length = rna_prop.array_length + except: length = 0 + + array_str = get_array_str(length) + + if rna_prop.editable: readonly_str = '' + else: readonly_str = ' (readonly)' + + if rna_prop_ptr: # Use the pointer type + out.write(ident+ '\t@ivar %s: %s\n' % (rna_prop_identifier, rna_desc)) + out.write(ident+ '\t@type %s: %sL{%s}%s%s\n' % (rna_prop_identifier, collection_str, rna_prop_ptr.identifier, array_str, readonly_str)) + else: + if rna_prop_type == 'enum': + if 0: + out.write(ident+ '\t@ivar %s: %s in (%s)\n' % (rna_prop_identifier, rna_desc, ', '.join(rna_prop.items.keys()))) + else: + out.write(ident+ '\t@ivar %s: %s in...\n' % (rna_prop_identifier, rna_desc)) + for e, e_rna_prop in rna_prop.items.items(): + #out.write(ident+ '\t\t- %s: %s\n' % (e, e_rna_prop.description)) # XXX - segfaults, FIXME + out.write(ident+ '\t\t- %s\n' % e) + + out.write(ident+ '\t@type %s: %s%s%s\n' % (rna_prop_identifier, rna_prop_type, array_str, readonly_str)) + elif rna_prop_type == 'int' or rna_prop_type == 'float': + out.write(ident+ '\t@ivar %s: %s\n' % (rna_prop_identifier, rna_desc)) + out.write(ident+ '\t@type %s: %s%s%s in [%s, %s]\n' % (rna_prop_identifier, rna_prop_type, array_str, readonly_str, range_str(rna_prop.hard_min), range_str(rna_prop.hard_max) )) + elif rna_prop_type == 'string': + out.write(ident+ '\t@ivar %s: %s (maximum length of %s)\n' % (rna_prop_identifier, rna_desc, rna_prop.max_length)) + out.write(ident+ '\t@type %s: %s%s%s\n' % (rna_prop_identifier, rna_prop_type, array_str, readonly_str)) + else: + out.write(ident+ '\t@ivar %s: %s\n' % (rna_prop_identifier, rna_desc)) + out.write(ident+ '\t@type %s: %s%s%s\n' % (rna_prop_identifier, rna_prop_type, array_str, readonly_str)) + + + out.write(ident+ '\t"""\n\n') + + + # Write functions + # for rna_func in rna_struct.functions: # Better ignore inherited (line below) + for rna_func in rna_functions_dict[identifier]: + if rna_func not in rna_base_func_keys: + write_func(rna_func, ident+'\t', out, 'FUNCTION') + + out.write('\n') + + # Now write children recursively + for child in rna_children_dict[identifier]: + write_struct(child, ident + '\t') + + + + # out = open(target_path, 'w') + out = open_submodule("types.py", BASEPATH) # bpy.types + + def base_id(rna_struct): + try: return rna_struct.base.identifier + except: return '' # invalid id + + #structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()] + ''' + structs = [] + 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) + + try: rna_struct = rna_type.bl_rna + except: rna_struct = None + + if rna_struct: + #if not rna_type_name.startswith('__'): + + identifier = rna_struct.identifier + + if not rna_id_ignore(identifier): + structs.append( (base_id(rna_struct), identifier, rna_struct) ) + + # Simple lookup + rna_struct_dict[identifier] = rna_struct + + # Store full rna path 'GameObjectSettings' -> 'Object.GameObjectSettings' + rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct) + + # Store a list of functions, remove inherited later + rna_functions_dict[identifier]= list(rna_struct.functions) + + + # fill in these later + rna_children_dict[identifier]= [] + rna_references_dict[identifier]= [] + + + else: + print("Ignoring", rna_type_name) + + + # Sucks but we need to copy this so we can check original parent functions + rna_functions_dict__copy = {} + for key, val in rna_functions_dict.items(): + rna_functions_dict__copy[key] = val[:] + + + 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 + deps_ok = False + while deps_ok == False: + deps_ok = True + rna_done = set() + + for i, (rna_base, identifier, rna_struct) in enumerate(structs): + + rna_done.add(identifier) + + if rna_base and rna_base not in rna_done: + deps_ok = False + data = structs.pop(i) + ok = False + while i < len(structs): + if structs[i][1]==rna_base: + structs.insert(i+1, data) # insert after the item we depend on. + ok = True + break + i+=1 + + if not ok: + print('Dependancy "%s" could not be found for "%s"' % (identifier, rna_base)) + + break + + # Done ordering structs + + + # precalc vars to avoid a lot of looping + for (rna_base, identifier, rna_struct) in structs: + + if rna_base: + rna_base_prop_keys = rna_struct_dict[rna_base].properties.keys() # could cache + rna_base_func_keys = [f.identifier for f in rna_struct_dict[rna_base].functions] + else: + rna_base_prop_keys = [] + rna_base_func_keys= [] + + # rna_struct_path = full_rna_struct_path(rna_struct) + rna_struct_path = rna_full_path_dict[identifier] + + for rna_prop_identifier, rna_prop in rna_struct.properties.items(): + + if rna_prop_identifier=='RNA': continue + if rna_id_ignore(rna_prop_identifier): continue + if rna_prop_identifier in rna_base_prop_keys: continue + + try: rna_prop_ptr = rna_prop.fixed_type + except: rna_prop_ptr = None + + # Does this property point to me? + if rna_prop_ptr: + rna_references_dict[rna_prop_ptr.identifier].append( "%s.%s" % (rna_struct_path, rna_prop_identifier) ) + + for rna_func in rna_struct.functions: + for rna_prop_identifier, rna_prop in rna_func.parameters.items(): + + if rna_prop_identifier=='RNA': continue + if rna_id_ignore(rna_prop_identifier): continue + if rna_prop_identifier in rna_base_func_keys: continue + + + try: rna_prop_ptr = rna_prop.fixed_type + except: rna_prop_ptr = None + + # Does this property point to me? + if rna_prop_ptr: + rna_references_dict[rna_prop_ptr.identifier].append( "%s.%s" % (rna_struct_path, rna_func.identifier) ) + + + # Store nested children + nested = rna_struct.nested + if nested: + rna_children_dict[nested.identifier].append(rna_struct) + + + if rna_base: + rna_funcs = rna_functions_dict[identifier] + if rna_funcs: + # Remove inherited functions if we have any + rna_base_funcs = rna_functions_dict__copy[rna_base] + rna_funcs[:] = [f for f in rna_funcs if f not in rna_base_funcs] + + rna_functions_dict__copy.clear() + del rna_functions_dict__copy + + # Sort the refs, just reads nicer + for rna_refs in rna_references_dict.values(): + rna_refs.sort() + + for (rna_base, identifier, rna_struct) in structs: + if rna_struct.nested: + continue + + write_struct(rna_struct, '') + + + out.write('\n') + out.close() + + # # We could also just run.... + # os.system('epydoc source/blender/python/doc/rna.py -o ./source/blender/python/doc/html -v') + + target_path = os.path.join(BASEPATH, "dump.py") # XXX - used for other funcs + + # Write graphviz + out= open(target_path.replace('.py', '.dot'), 'w') + out.write('digraph "rna data api" {\n') + out.write('\tnode [style=filled, shape = "box"];\n') + out.write('\toverlap=false;\n') + out.write('\trankdir = LR;\n') + out.write('\tsplines=true;\n') + out.write('\tratio=auto;\n') + + + + out.write('\tsize="10,10"\n') + #out.write('\tpage="8.5,11"\n') + #out.write('\tcenter=""\n') + + def isop(rna_struct): + return '_OT_' in rna_struct.identifier + + + for (rna_base, identifier, rna_struct) in structs: + if isop(rna_struct): + continue + + base = rna_struct.base + + + out.write('\t"%s";\n' % identifier) + + for (rna_base, identifier, rna_struct) in structs: + + if isop(rna_struct): + continue + + base = rna_struct.base + + if base and not isop(base): + out.write('\t"%s" -> "%s" [label="(base)" weight=1.0];\n' % (base.identifier, identifier)) + + nested = rna_struct.nested + if nested and not isop(nested): + out.write('\t"%s" -> "%s" [label="(nested)" weight=1.0];\n' % (nested.identifier, identifier)) + + + + rna_refs= rna_references_dict[identifier] + + for rna_ref_string in rna_refs: + + if '_OT_' in rna_ref_string: + continue + + ref = rna_ref_string.split('.')[-2] + out.write('\t"%s" -> "%s" [label="%s" weight=0.01];\n' % (ref, identifier, rna_ref_string)) + + + out.write('}\n') + out.close() + + # # We could also just run.... + # os.system('dot source/blender/python/doc/rna.dot -Tsvg -o ./source/blender/python/doc/rna.svg') + + + out= open(target_path.replace('.py', '.words'), 'w') + rna_words = list(rna_words) + rna_words.sort() + for w in rna_words: + out.write('%s\n' % w) + def op2epy(BASEPATH): - # out = open(target_path, 'w') - - op_mods = dir(bpy.ops) - op_mods.remove('add') - op_mods.remove('remove') - - for op_mod_name in sorted(op_mods): - if op_mod_name.startswith('__'): - continue - - # open the submodule - mod_path = os.path.join("ops", op_mod_name + ".py") - out = open_submodule(mod_path, BASEPATH) - - - op_mod = getattr(bpy.ops, op_mod_name) - operators = dir(op_mod) - for op in sorted(operators): - # rna = getattr(bpy.types, op).bl_rna - rna = getattr(op_mod, op).get_rna() - write_func(rna, '', out, 'OPERATOR') - - out.write('\n') - out.close() + # out = open(target_path, 'w') + + op_mods = dir(bpy.ops) + op_mods.remove('add') + op_mods.remove('remove') + + for op_mod_name in sorted(op_mods): + if op_mod_name.startswith('__'): + continue + + # open the submodule + mod_path = os.path.join("ops", op_mod_name + ".py") + out = open_submodule(mod_path, BASEPATH) + + + op_mod = getattr(bpy.ops, op_mod_name) + operators = dir(op_mod) + for op in sorted(operators): + # rna = getattr(bpy.types, op).bl_rna + rna = getattr(op_mod, op).get_rna() + write_func(rna, '', out, 'OPERATOR') + + out.write('\n') + out.close() def misc2epy(BASEPATH): - ''' - Hard coded modules, try to avoid adding stuff here - ''' - - f = append_package(os.path.join(BASEPATH, ""), ""); # add a slash on the end of the base path - f.write(''' + ''' + Hard coded modules, try to avoid adding stuff here + ''' + + f = append_package(os.path.join(BASEPATH, ""), ""); # add a slash on the end of the base path + f.write(''' """ @type data: L{bpy.types.Main} @var data: blender data is accessed from here """ ''') - f = open_submodule("props.py", BASEPATH) - f.write(''' + f = open_submodule("props.py", BASEPATH) + f.write(''' MAX_INT= 2**31 MAX_FLOAT= 1e+37 def BoolProperty(attr, name="", description="", default=False): - """ - return a new bool property - """ + """ + return a new bool property + """ def IntProperty(attr, name="", description="", min=-MAX_INT, max=MAX_INT, soft_min=-MAX_INT, soft_max=MAX_INT, default=0): - """ - return a new int property - """ + """ + return a new int property + """ def FloatProperty(attr, name="", description="", min=-MAX_FLOAT, max=MAX_FLOAT, soft_min=-MAX_FLOAT, soft_max=MAX_FLOAT, default=0.0): - """ - return a new float property - """ + """ + return a new float property + """ def StringProperty(attr, name="", description="", maxlen=0, default=""): - """ - return a new string property - """ + """ + return a new string property + """ def EnumProperty(attr, items, name="", description="", default=""): - """ - return a new enum property - """ + """ + return a new enum property + """ ''') if __name__ == '__main__': - if 'bpy' not in dir(): - print("\nError, this script must run from inside blender2.5") - print(script_help_msg) - else: - misc2epy('source/blender/python/doc/bpy') # first to write in info in some of the modules. - rna2epy('source/blender/python/doc/bpy') - op2epy('source/blender/python/doc/bpy') - - - close_all() - - import sys - sys.exit() + if 'bpy' not in dir(): + print("\nError, this script must run from inside blender2.5") + print(script_help_msg) + else: + misc2epy('source/blender/python/doc/bpy') # first to write in info in some of the modules. + rna2epy('source/blender/python/doc/bpy') + op2epy('source/blender/python/doc/bpy') + + + close_all() + + import sys + sys.exit() diff --git a/source/blender/python/rna_dump.py b/source/blender/python/rna_dump.py index 7dde4007f66..7c53a6cc235 100644 --- a/source/blender/python/rna_dump.py +++ b/source/blender/python/rna_dump.py @@ -19,114 +19,114 @@ # #**** END GPL LICENSE BLOCK #**** if 1: - # Print once every 1000 - GEN_PATH = True - PRINT_DATA = False - PRINT_DATA_INT = 1000 - VERBOSE = False - VERBOSE_TYPE = False - MAX_RECURSIVE = 8 + # Print once every 1000 + GEN_PATH = True + PRINT_DATA = False + PRINT_DATA_INT = 1000 + VERBOSE = False + VERBOSE_TYPE = False + MAX_RECURSIVE = 8 else: - # Print everything - GEN_PATH = True - PRINT_DATA = True - PRINT_DATA_INT = 0 - VERBOSE = False - VERBOSE_TYPE = False - MAX_RECURSIVE = 8 + # Print everything + GEN_PATH = True + PRINT_DATA = True + PRINT_DATA_INT = 0 + VERBOSE = False + VERBOSE_TYPE = False + MAX_RECURSIVE = 8 seek_count = [0] def seek(r, txt, recurs): - - seek_count[0] += 1 - - if PRINT_DATA_INT: - if not (seek_count[0] % PRINT_DATA_INT): - print(seek_count[0], txt) - - if PRINT_DATA: - print(txt) - - newtxt = '' - - if recurs > MAX_RECURSIVE: - #print ("Recursion is over max") - #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 GEN_PATH: newtxt = txt + '.' + item - - if item == 'rna_type' and VERBOSE_TYPE==False: # just avoid because it spits out loads of data - continue - - try: value = getattr(r, item) - except: value = None - - seek( value, newtxt, recurs + 1) - - - if keys: - for k in keys: - if GEN_PATH: newtxt = txt + '["' + k + '"]' - seek(r.__getitem__(k), newtxt, recurs+1) - - 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 GEN_PATH: newtxt = txt + '[' + str(i) + ']' - seek(r[i], newtxt, recurs+1) - else: - for i in range(length): - if GEN_PATH: newtxt = txt + '[' + str(i) + ']' - seek(r[i], newtxt, recurs+1) + + seek_count[0] += 1 + + if PRINT_DATA_INT: + if not (seek_count[0] % PRINT_DATA_INT): + print(seek_count[0], txt) + + if PRINT_DATA: + print(txt) + + newtxt = '' + + if recurs > MAX_RECURSIVE: + #print ("Recursion is over max") + #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 GEN_PATH: newtxt = txt + '.' + item + + if item == 'rna_type' and VERBOSE_TYPE==False: # just avoid because it spits out loads of data + continue + + try: value = getattr(r, item) + except: value = None + + seek( value, newtxt, recurs + 1) + + + if keys: + for k in keys: + if GEN_PATH: newtxt = txt + '["' + k + '"]' + seek(r.__getitem__(k), newtxt, recurs+1) + + 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 GEN_PATH: newtxt = txt + '[' + str(i) + ']' + seek(r[i], newtxt, recurs+1) + else: + for i in range(length): + if GEN_PATH: newtxt = txt + '[' + str(i) + ']' + seek(r[i], newtxt, recurs+1) seek(bpy.data, 'bpy.data', 0) # seek(bpy.types, 'bpy.types', 0) ''' for d in dir(bpy.types): - t = getattr(bpy.types, d) - try: r = t.bl_rna - except: r = None - if r: - seek(r, 'bpy.types.' + d + '.bl_rna', 0) + t = getattr(bpy.types, d) + try: r = t.bl_rna + except: r = None + if r: + seek(r, 'bpy.types.' + d + '.bl_rna', 0) ''' #print dir(bpy) diff --git a/source/blender/python/simple_enum_gen.py b/source/blender/python/simple_enum_gen.py index 59f048c2842..615d48b77d0 100644 --- a/source/blender/python/simple_enum_gen.py +++ b/source/blender/python/simple_enum_gen.py @@ -19,47 +19,47 @@ # #**** END GPL LICENSE BLOCK #**** defs = """ - SPACE_EMPTY, - SPACE_VIEW3D, - SPACE_IPO, - SPACE_OUTLINER, - 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 + SPACE_EMPTY, + SPACE_VIEW3D, + SPACE_IPO, + SPACE_OUTLINER, + 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) - + + 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) + |