This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/python/epy_doc_gen.py
Campbell Barton 64512d3e8e WIP PyAPI from winter camp discussions, make subtypes of the base RNA python type, eventually allowing us to have python defined RNA classes in
python - lux/pov/renderman materials, lamps etc as well as operators.

At the moment there are 2 ways to do this, The first is like subclassing from python, another (disabled) method copies the base PyTypeObject struct 
and makes some changes.

The PyType is stored in the RNA Struct for reuse, right now there are no access functions - needs to be improved.

Added a python script for printing all blend file data to the console which helps testing the api.

dir(rna) wont work for python 2.x now, use rna.__dir__() instead.
2009-03-11 17:28:37 +00:00

291 lines
8.7 KiB
Python

# ***** 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 #****
# Usage,
# run this script from blenders root path once you have compiled blender
# ./blender.bin -b -P source/blender/python/epy_doc_gen.py
#
# This will generate rna.py, generate html docs by running...
# epydoc source/blender/python/doc/rna.py -o source/blender/python/doc/html -v --no-sourcecode --name="RNA API" --url="http://brechtvanlommelfanclub.com" --graph=classtree
#
# 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 get_array_str(length):
if length > 0: return ' array of %d items' % length
else: return ''
def rna2epy(target_path):
def write_struct(rna_struct, structs, ident):
identifier = rna_struct.identifier
rna_base = rna_struct.base
if rna_base:
out.write(ident+ 'class %s(%s):\n' % (identifier, rna_base.identifier))
else:
out.write(ident+ 'class %s:\n' % identifier)
out.write(ident+ '\t"""\n')
title = 'The %s Object' % rna_struct.name
out.write(ident+ '\t%s\n' % title)
out.write(ident+ '\t%s\n' % ('=' * len(title)))
out.write(ident+ '\t\t%s\n' % rna_struct.description)
for rna_prop_identifier, rna_prop in rna_struct.properties.items():
if rna_prop_identifier=='RNA':
continue
if rna_prop_identifier=='rna_type':
continue
rna_desc = rna_prop.description
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':
out.write(ident+ '\t@ivar %s: %s in (%s)\n' % (rna_prop_identifier, rna_desc, ', '.join(rna_prop.items.keys())))
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')
# Now write children recursively
for child in structs:
if rna_struct == child.nested:
write_struct(child, structs, ident + '\t')
out = open(target_path, 'w')
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 bpydoc.structs.values()]
structs = []
for rna_struct in bpydoc.structs.values():
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
# 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
structs = [data[2] for data in structs]
# Done ordering structs
for rna_struct in structs:
# print(type(rna_struct))
if rna_struct.nested:
continue
write_struct(rna_struct, structs, '')
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')
def op2epy(target_path):
out = open(target_path, 'w')
operators = dir(bpyoperator)
operators.remove('add')
operators.remove('remove')
operators.sort()
for op in operators:
if op.startswith('__'):
continue
# 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 (dir(rna))
# print (dir(rna_struct))
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: length = rna_prop.array_length
except: length = 0
array_str = get_array_str(length)
try:
val = getattr(rna, rna_prop_identifier)
except:
val = '<UNDEFINED>'
kw_type_str= "@type %s: %s%s" % (rna_prop_identifier, rna_prop_type, array_str)
kw_param_str= "@param %s: %s" % (rna_prop_identifier, rna_prop.description)
kw_param_set = False
if rna_prop_type=='float':
if length==0:
val_str= '%g' % val
if '.' not in val_str:
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
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
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')
out.write('\t%s\n' % rna_struct.description)
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')