initial sphinx doc generation support for python and C modules.
python modules bpy.app, bpy.utils are now included in docs. C defined python module bpy.props has its docstrings extracted and written directly into sphinx docs since the C methods cant be inspected. added docstrings to bpy.props and improved some in bpy.utils. will update online docs tomorrow.
This commit is contained in:
@@ -49,6 +49,114 @@ def write_indented_lines(ident, fn, text):
|
||||
for l in text.split("\n"):
|
||||
fn(ident + l.strip() + "\n")
|
||||
|
||||
|
||||
def pymethod2sphinx(ident, fw, identifier, py_func):
|
||||
'''
|
||||
class method to sphinx
|
||||
'''
|
||||
arg_str = inspect.formatargspec(*inspect.getargspec(py_func))
|
||||
if arg_str.startswith("(self, "):
|
||||
arg_str = "(" + arg_str[7:]
|
||||
func_type = "method"
|
||||
elif arg_str.startswith("(cls, "):
|
||||
arg_str = "(" + arg_str[6:]
|
||||
func_type = "classmethod"
|
||||
else:
|
||||
func_type = "staticmethod"
|
||||
|
||||
fw(ident + ".. %s:: %s%s\n\n" % (func_type, identifier, arg_str))
|
||||
if py_func.__doc__:
|
||||
write_indented_lines(ident + " ", fw, py_func.__doc__)
|
||||
fw("\n")
|
||||
|
||||
|
||||
def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
|
||||
'''
|
||||
function or class method to sphinx
|
||||
'''
|
||||
arg_str = inspect.formatargspec(*inspect.getargspec(py_func))
|
||||
|
||||
if not is_class:
|
||||
func_type = "function"
|
||||
|
||||
# ther rest are class methods
|
||||
elif arg_str.startswith("(self, "):
|
||||
arg_str = "(" + arg_str[7:]
|
||||
func_type = "method"
|
||||
elif arg_str.startswith("(cls, "):
|
||||
arg_str = "(" + arg_str[6:]
|
||||
func_type = "classmethod"
|
||||
else:
|
||||
func_type = "staticmethod"
|
||||
|
||||
fw(ident + ".. %s:: %s%s\n\n" % (func_type, identifier, arg_str))
|
||||
if py_func.__doc__:
|
||||
write_indented_lines(ident + " ", fw, py_func.__doc__.strip())
|
||||
fw("\n")
|
||||
|
||||
def py_c_func2sphinx(ident, fw, identifier, py_func, is_class=True):
|
||||
'''
|
||||
c defined function to sphinx.
|
||||
'''
|
||||
|
||||
# dump the docstring, assume its formatted correctly
|
||||
if py_func.__doc__:
|
||||
for l in py_func.__doc__.split("\n"):
|
||||
fw(ident + l + "\n")
|
||||
fw("\n")
|
||||
else:
|
||||
fw(ident + ".. function:: %s()\n\n" % identifier)
|
||||
fw(ident + " Undocumented function.\n\n" % identifier)
|
||||
|
||||
|
||||
def pyprop2sphinx(ident, fw, identifier, py_prop):
|
||||
'''
|
||||
python property to sphinx
|
||||
'''
|
||||
fw(ident + ".. attribute:: %s\n\n" % identifier)
|
||||
write_indented_lines(ident + " ", fw, py_prop.__doc__)
|
||||
if py_prop.fset is None:
|
||||
fw(ident + " (readonly)\n\n")
|
||||
|
||||
|
||||
def pymodule2sphinx(BASEPATH, module_name, module, title):
|
||||
import types
|
||||
|
||||
filepath = os.path.join(BASEPATH, module_name + ".rst")
|
||||
|
||||
file = open(filepath, "w")
|
||||
print(filepath)
|
||||
print(filepath)
|
||||
fw = file.write
|
||||
|
||||
fw(title + "\n")
|
||||
fw(("=" * len(title)) + "\n\n")
|
||||
|
||||
fw(".. module:: %s\n\n" % module_name)
|
||||
|
||||
if module.__doc__:
|
||||
# Note, may contain sphinx syntax, dont mangle!
|
||||
fw(module.__doc__.strip())
|
||||
fw("\n\n")
|
||||
|
||||
for attribute in dir(module):
|
||||
if not attribute.startswith("_"):
|
||||
value = getattr(module, attribute)
|
||||
|
||||
value_type = type(value)
|
||||
print(attribute, value_type)
|
||||
if value_type == types.FunctionType:
|
||||
pyfunc2sphinx("", fw, attribute, value, is_class=False)
|
||||
elif value_type in (types.BuiltinMethodType, types.BuiltinFunctionType): # both the same at the moment but to be future proof
|
||||
# note: can't get args from these, so dump the string as is
|
||||
# this means any module used like this must have fully formatted docstrings.
|
||||
py_c_func2sphinx("", fw, attribute, value, is_class=False)
|
||||
|
||||
# TODO, more types...
|
||||
|
||||
file.close()
|
||||
|
||||
|
||||
def rna2sphinx(BASEPATH):
|
||||
|
||||
structs, funcs, ops, props = rna_info.BuildRNAInfo()
|
||||
@@ -80,8 +188,27 @@ def rna2sphinx(BASEPATH):
|
||||
fw(" :glob:\n\n")
|
||||
fw(" bpy.ops.*\n\n")
|
||||
fw(" bpy.types.*\n\n")
|
||||
|
||||
# py modules
|
||||
fw(" bpy.utils\n\n")
|
||||
fw(" bpy.app\n\n")
|
||||
|
||||
# C modules
|
||||
fw(" bpy.props\n\n")
|
||||
|
||||
file.close()
|
||||
|
||||
# python modules
|
||||
from bpy import utils as module
|
||||
pymodule2sphinx(BASEPATH, "bpy.utils", module, "Blender Python Utilities")
|
||||
from bpy import app as module
|
||||
pymodule2sphinx(BASEPATH, "bpy.app", module, "Blender Python Application Constants")
|
||||
|
||||
from bpy import props as module
|
||||
pymodule2sphinx(BASEPATH, "bpy.props", module, "Blender Python Property Definitions")
|
||||
del module
|
||||
|
||||
|
||||
if 0:
|
||||
filepath = os.path.join(BASEPATH, "bpy.rst")
|
||||
file = open(filepath, "w")
|
||||
@@ -167,10 +294,7 @@ def rna2sphinx(BASEPATH):
|
||||
py_properties = struct.get_py_properties()
|
||||
py_prop = None
|
||||
for identifier, py_prop in py_properties:
|
||||
fw(" .. attribute:: %s\n\n" % identifier)
|
||||
write_indented_lines(" ", fw, py_prop.__doc__)
|
||||
if py_prop.fset is None:
|
||||
fw(" (readonly)\n\n")
|
||||
pyprop2sphinx(" ", fw, identifier, py_prop)
|
||||
del py_properties, py_prop
|
||||
|
||||
for func in struct.functions:
|
||||
@@ -201,20 +325,7 @@ def rna2sphinx(BASEPATH):
|
||||
py_func = None
|
||||
|
||||
for identifier, py_func in py_funcs:
|
||||
arg_str = inspect.formatargspec(*inspect.getargspec(py_func))
|
||||
if arg_str.startswith("(self, "):
|
||||
arg_str = "(" + arg_str[7:]
|
||||
func_type = "method"
|
||||
elif arg_str.startswith("(cls, "):
|
||||
arg_str = "(" + arg_str[6:]
|
||||
func_type = "classmethod"
|
||||
else:
|
||||
func_type = "staticmethod"
|
||||
|
||||
fw(" .. %s:: %s%s\n\n" % (func_type, identifier, arg_str))
|
||||
if py_func.__doc__:
|
||||
write_indented_lines(" ", fw, py_func.__doc__)
|
||||
fw("\n")
|
||||
pyfunc2sphinx(" ", fw, identifier, py_func, is_class=True)
|
||||
del py_funcs, py_func
|
||||
|
||||
if struct.references:
|
||||
|
||||
Reference in New Issue
Block a user