Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-05-21 09:33:35 +0300
committerCampbell Barton <campbell@blender.org>2022-05-22 06:08:38 +0300
commit84901adec55eb1472652a315e3401a53787efcb6 (patch)
tree6fabcfdd4ce298e774024ecb43854262f8f4b64b /doc
parentdfb8c90324c018068f12ca41543c3c311dff6d21 (diff)
PyDoc: cleanup doc-generator
- Full sentences for comments. - Use double quotes for strings (which aren't enum ID's). - Reduce right-shift.
Diffstat (limited to 'doc')
-rw-r--r--doc/python_api/sphinx_doc_gen.py553
1 files changed, 292 insertions, 261 deletions
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 0a20bd83c22..24b94f170c7 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -2,8 +2,7 @@
# <pep8 compliant>
-SCRIPT_HELP_MSG = """
-
+"""
API dump in RST files
---------------------
Run this script from Blender's root path once you have compiled Blender
@@ -36,18 +35,17 @@ Sphinx: PDF generation
sphinx-build -b latex doc/python_api/sphinx-in doc/python_api/sphinx-out
cd doc/python_api/sphinx-out
make
-
"""
try:
- import bpy # Blender module
+ import bpy # Blender module.
except ImportError:
print("\nERROR: this script must run from inside Blender")
- print(SCRIPT_HELP_MSG)
+ print(__doc__)
import sys
sys.exit()
-import rna_info # Blender module
+import rna_info # Blender module.
def rna_info_BuildRNAInfo_cache():
@@ -74,10 +72,10 @@ PLATFORM = platform().split('-')[0].lower() # 'linux', 'darwin', 'windows'
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
-# For now, ignore add-ons and internal subclasses of 'bpy.types.PropertyGroup'.
+# For now, ignore add-ons and internal sub-classes of `bpy.types.PropertyGroup`.
#
# Besides disabling this line, the main change will be to add a
-# 'toctree' to 'write_rst_index' which contains the generated rst files.
+# 'toctree' to 'write_rst_index' which contains the generated RST files.
# This 'toctree' can be generated automatically.
#
# See: D6261 for reference.
@@ -85,92 +83,109 @@ USE_ONLY_BUILTIN_RNA_TYPES = True
def handle_args():
- '''
+ """
Parse the args passed to Blender after "--", ignored by Blender
- '''
+ """
import argparse
# When --help is given, print the usage text
parser = argparse.ArgumentParser(
formatter_class=argparse.RawTextHelpFormatter,
- usage=SCRIPT_HELP_MSG
+ usage=__doc__
)
# optional arguments
- parser.add_argument("-p", "--partial",
- dest="partial",
- type=str,
- default="",
- help="Use a wildcard to only build specific module(s)\n"
- "Example: --partial bmesh*\n",
- required=False)
-
- parser.add_argument("-f", "--fullrebuild",
- dest="full_rebuild",
- default=False,
- action='store_true',
- help="Rewrite all rst files in sphinx-in/ "
- "(default=False)",
- required=False)
-
- parser.add_argument("-b", "--bpy",
- dest="bpy",
- default=False,
- action='store_true',
- help="Write the rst file of the bpy module "
- "(default=False)",
- required=False)
-
- parser.add_argument("-o", "--output",
- dest="output_dir",
- type=str,
- default=SCRIPT_DIR,
- help="Path of the API docs (default=<script dir>)",
- required=False)
-
- parser.add_argument("-B", "--sphinx-build",
- dest="sphinx_build",
- default=False,
- action='store_true',
- help="Build the html docs by running:\n"
- "sphinx-build SPHINX_IN SPHINX_OUT\n"
- "(default=False; does not depend on -P)",
- required=False)
-
- parser.add_argument("-P", "--sphinx-build-pdf",
- dest="sphinx_build_pdf",
- default=False,
- action='store_true',
- help="Build the pdf by running:\n"
- "sphinx-build -b latex SPHINX_IN SPHINX_OUT_PDF\n"
- "(default=False; does not depend on -B)",
- required=False)
-
- parser.add_argument("-R", "--pack-reference",
- dest="pack_reference",
- default=False,
- action='store_true',
- help="Pack all necessary files in the deployed dir.\n"
- "(default=False; use with -B and -P)",
- required=False)
-
- parser.add_argument("-l", "--log",
- dest="log",
- default=False,
- action='store_true',
- help="Log the output of the API dump and sphinx|latex "
- "warnings and errors (default=False).\n"
- "If given, save logs in:\n"
- "* OUTPUT_DIR/.bpy.log\n"
- "* OUTPUT_DIR/.sphinx-build.log\n"
- "* OUTPUT_DIR/.sphinx-build_pdf.log\n"
- "* OUTPUT_DIR/.latex_make.log",
- required=False)
-
- # parse only the args passed after '--'
+ parser.add_argument(
+ "-p", "--partial",
+ dest="partial",
+ type=str,
+ default="",
+ help="Use a wildcard to only build specific module(s)\n"
+ "Example: --partial bmesh*\n",
+ required=False,)
+
+ parser.add_argument(
+ "-f", "--fullrebuild",
+ dest="full_rebuild",
+ default=False,
+ action='store_true',
+ help="Rewrite all RST files in sphinx-in/ "
+ "(default=False)",
+ required=False,
+ )
+
+ parser.add_argument(
+ "-b", "--bpy",
+ dest="bpy",
+ default=False,
+ action='store_true',
+ help="Write the RST file of the bpy module "
+ "(default=False)",
+ required=False,
+ )
+
+ parser.add_argument(
+ "-o", "--output",
+ dest="output_dir",
+ type=str,
+ default=SCRIPT_DIR,
+ help="Path of the API docs (default=<script dir>)",
+ required=False,
+ )
+
+ parser.add_argument(
+ "-B", "--sphinx-build",
+ dest="sphinx_build",
+ default=False,
+ action='store_true',
+ help="Build the html docs by running:\n"
+ "sphinx-build SPHINX_IN SPHINX_OUT\n"
+ "(default=False; does not depend on -P)",
+ required=False,
+ )
+
+ parser.add_argument(
+ "-P", "--sphinx-build-pdf",
+ dest="sphinx_build_pdf",
+ default=False,
+ action='store_true',
+ help="Build the pdf by running:\n"
+ "sphinx-build -b latex SPHINX_IN SPHINX_OUT_PDF\n"
+ "(default=False; does not depend on -B)",
+ required=False,
+ )
+
+ parser.add_argument(
+ "-R", "--pack-reference",
+ dest="pack_reference",
+ default=False,
+ action='store_true',
+ help="Pack all necessary files in the deployed dir.\n"
+ "(default=False; use with -B and -P)",
+ required=False,
+ )
+
+ parser.add_argument(
+ "-l", "--log",
+ dest="log",
+ default=False,
+ action='store_true',
+ help=(
+ "Log the output of the API dump and sphinx|latex "
+ "warnings and errors (default=False).\n"
+ "If given, save logs in:\n"
+ "* OUTPUT_DIR/.bpy.log\n"
+ "* OUTPUT_DIR/.sphinx-build.log\n"
+ "* OUTPUT_DIR/.sphinx-build_pdf.log\n"
+ "* OUTPUT_DIR/.latex_make.log"
+ ),
+ required=False,
+ )
+
+ # Parse only the arguments passed after "--".
argv = []
if "--" in sys.argv:
- argv = sys.argv[sys.argv.index("--") + 1:] # get all args after "--"
+ argv = sys.argv[sys.argv.index("--") + 1:] # Get all arguments after "--".
return parser.parse_args(argv)
@@ -179,7 +194,7 @@ ARGS = handle_args()
# ----------------------------------BPY-----------------------------------------
-BPY_LOGGER = logging.getLogger('bpy')
+BPY_LOGGER = logging.getLogger("bpy")
BPY_LOGGER.setLevel(logging.DEBUG)
"""
@@ -193,7 +208,7 @@ or
./blender -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B
"""
-# Switch for quick testing so doc-builds don't take so long
+# Switch for quick testing so doc-builds don't take so long.
if not ARGS.partial:
# full build
FILTER_BPY_OPS = None
@@ -261,7 +276,7 @@ else:
# ------
# Filter
#
- # TODO, support bpy.ops and bpy.types filtering
+ # TODO: support `bpy.ops` and `bpy.types` filtering.
import fnmatch
m = None
EXCLUDE_MODULES = [m for m in EXCLUDE_MODULES if not fnmatch.fnmatchcase(m, ARGS.partial)]
@@ -293,13 +308,13 @@ else:
try:
__import__("aud")
except ImportError:
- BPY_LOGGER.debug("Warning: Built without 'aud' module, docs incomplete...")
+ BPY_LOGGER.debug("Warning: Built without \"aud\" module, docs incomplete...")
EXCLUDE_MODULES.append("aud")
try:
__import__("freestyle")
except ImportError:
- BPY_LOGGER.debug("Warning: Built without 'freestyle' module, docs incomplete...")
+ BPY_LOGGER.debug("Warning: Built without \"freestyle\" module, docs incomplete...")
EXCLUDE_MODULES.extend([
"freestyle",
"freestyle.chainingiterators",
@@ -335,7 +350,7 @@ for f in os.listdir(EXAMPLES_DIR):
EXAMPLE_SET.add(os.path.splitext(f)[0])
EXAMPLE_SET_USED = set()
-# rst files dir
+# RST files directory.
RST_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "rst"))
# extra info, not api reference docs
@@ -364,33 +379,33 @@ RNA_BLACKLIST = {
MODULE_GROUPING = {
"bmesh.types": (
- ("Base Mesh Type", '-'),
+ ("Base Mesh Type", "-"),
"BMesh",
- ("Mesh Elements", '-'),
+ ("Mesh Elements", "-"),
"BMVert",
"BMEdge",
"BMFace",
"BMLoop",
- ("Sequence Accessors", '-'),
+ ("Sequence Accessors", "-"),
"BMElemSeq",
"BMVertSeq",
"BMEdgeSeq",
"BMFaceSeq",
"BMLoopSeq",
"BMIter",
- ("Selection History", '-'),
+ ("Selection History", "-"),
"BMEditSelSeq",
"BMEditSelIter",
- ("Custom-Data Layer Access", '-'),
+ ("Custom-Data Layer Access", "-"),
"BMLayerAccessVert",
"BMLayerAccessEdge",
"BMLayerAccessFace",
"BMLayerAccessLoop",
"BMLayerCollection",
"BMLayerItem",
- ("Custom-Data Layer Types", '-'),
+ ("Custom-Data Layer Types", "-"),
"BMLoopUV",
- "BMDeformVert"
+ "BMDeformVert",
)
}
@@ -419,7 +434,7 @@ else:
BLENDER_VERSION_HASH_HTML_LINK = BLENDER_VERSION_HASH
BLENDER_VERSION_DATE = time.strftime("%Y-%m-%d")
-# '2_83'
+# Example: `2_83`.
BLENDER_VERSION_PATH = "%d_%d" % (bpy.app.version[0], bpy.app.version[1])
# --------------------------DOWNLOADABLE FILES----------------------------------
@@ -470,8 +485,8 @@ if ARGS.sphinx_build_pdf:
# --------------------------------API DUMP--------------------------------------
-# lame, python won't give some access
-ClassMethodDescriptorType = type(dict.__dict__['fromkeys'])
+# Lame, python won't give some access.
+ClassMethodDescriptorType = type(dict.__dict__["fromkeys"])
MethodDescriptorType = type(dict.get)
GetSetDescriptorType = type(int.real)
StaticMethodType = type(staticmethod(lambda: None))
@@ -503,7 +518,8 @@ def import_value_from_module(module_name, import_name):
def escape_rst(text):
- """ Escape plain text which may contain characters used by RST.
+ """
+ Escape plain text which may contain characters used by RST.
"""
return text.translate(escape_rst.trans)
@@ -525,28 +541,28 @@ def undocumented_message(module_name, type_name, identifier):
def range_str(val):
- '''
+ """
Converts values to strings for the range directive.
(unused function it seems)
- '''
+ """
if val < -10000000:
- return '-inf'
+ return "-inf"
elif val > 10000000:
- return 'inf'
+ return "inf"
elif type(val) == float:
- return '%g' % val
+ return "%g" % val
else:
return str(val)
def example_extract_docstring(filepath):
- '''
+ """
Return (text, line_no, line_no_has_content) where:
- ``text`` is the doc-string text.
- ``line_no`` is the line the doc-string text ends.
- ``line_no_has_content`` when False, this file only contains a doc-string.
There is no need to include the remainder.
- '''
+ """
file = open(filepath, "r", encoding="utf-8")
line = file.readline()
line_no = 0
@@ -590,7 +606,7 @@ def title_string(text, heading_char, double=False):
def write_example_ref(ident, fw, example_id, ext="py"):
if example_id in EXAMPLE_SET:
- # extract the comment
+ # Extract the comment.
filepath = os.path.join("..", "examples", "%s.%s" % (example_id, ext))
filepath_full = os.path.join(os.path.dirname(fw.__self__.name), filepath)
@@ -615,7 +631,7 @@ def write_example_ref(ident, fw, example_id, ext="py"):
if bpy.app.debug:
BPY_LOGGER.debug("\tskipping example: " + example_id)
- # Support for numbered files bpy.types.Operator -> bpy.types.Operator.1.py
+ # Support for numbered files `bpy.types.Operator` -> `bpy.types.Operator.1.py`.
i = 1
while True:
example_id_num = "%s.%d" % (example_id, i)
@@ -627,22 +643,22 @@ def write_example_ref(ident, fw, example_id, ext="py"):
def write_indented_lines(ident, fn, text, strip=True):
- '''
- Apply same indentation to all lines in a multilines text.
- '''
+ """
+ Apply same indentation to all lines in a multi-lines text.
+ """
if text is None:
return
lines = text.split("\n")
- # strip empty lines from the start/end
+ # Strip empty lines from the start/end.
while lines and not lines[0].strip():
del lines[0]
while lines and not lines[-1].strip():
del lines[-1]
if strip:
- # set indentation to <indent>
+ # Set indentation to `<indent>`.
ident_strip = 1000
for l in lines:
if l.strip():
@@ -650,15 +666,15 @@ def write_indented_lines(ident, fn, text, strip=True):
for l in lines:
fn(ident + l[ident_strip:] + "\n")
else:
- # add <indent> number of blanks to the current indentation
+ # Add <indent> number of blanks to the current indentation.
for l in lines:
fn(ident + l + "\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:]
@@ -676,9 +692,9 @@ def pymethod2sphinx(ident, fw, identifier, py_func):
def pyfunc2sphinx(ident, fw, module_name, type_name, identifier, py_func, is_class=True):
- '''
+ """
function or class method to sphinx
- '''
+ """
if type(py_func) == MethodType:
return
@@ -688,7 +704,7 @@ def pyfunc2sphinx(ident, fw, module_name, type_name, identifier, py_func, is_cla
if not is_class:
func_type = "function"
- # the rest are class methods
+ # The rest are class methods.
elif arg_str.startswith("(self, ") or arg_str == "(self)":
arg_str = "()" if (arg_str == "(self)") else ("(" + arg_str[7:])
func_type = "method"
@@ -728,7 +744,7 @@ def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
fw(ident + ".. attribute:: %s\n\n" % identifier)
write_indented_lines(ident + " ", fw, doc, False)
fw("\n")
- elif type(descr) == MemberDescriptorType: # same as above but use 'data'
+ elif type(descr) == MemberDescriptorType: # same as above but use "data"
fw(ident + ".. data:: %s\n\n" % identifier)
write_indented_lines(ident + " ", fw, doc, False)
fw("\n")
@@ -743,11 +759,11 @@ def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
def py_c_func2sphinx(ident, fw, module_name, type_name, identifier, py_func, is_class=True):
- '''
- c defined function to sphinx.
- '''
+ """
+ C defined function to sphinx.
+ """
- # dump the docstring, assume its formatted correctly
+ # Dump the doc-string, assume its formatted correctly.
if py_func.__doc__:
write_indented_lines(ident, fw, py_func.__doc__, False)
fw("\n")
@@ -764,10 +780,10 @@ def py_c_func2sphinx(ident, fw, module_name, type_name, identifier, py_func, is_
def pyprop2sphinx(ident, fw, identifier, py_prop):
- '''
+ """
Python property to sphinx
- '''
- # readonly properties use "data" directive, variables use "attribute" directive
+ """
+ # Read-only properties use "data" directive, variables use "attribute" directive.
if py_prop.fset is None:
fw(ident + ".. data:: %s\n\n" % identifier)
else:
@@ -789,8 +805,8 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
if module_all:
module_dir = module_all
- # TODO - currently only used for classes
- # grouping support
+ # TODO: currently only used for classes.
+ # Grouping support.
module_grouping = MODULE_GROUPING.get(module_name)
def module_grouping_index(name):
@@ -810,7 +826,7 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
def module_grouping_sort_key(name):
return module_grouping_index(name)
- # done grouping support
+ # Done grouping support.
file = open(filepath, "w", encoding="utf-8")
@@ -825,8 +841,8 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
fw(module.__doc__.strip())
fw("\n\n")
- # write submodules
- # we could also scan files but this ensures __all__ is used correctly
+ # Write sub-modules.
+ # We could also scan files but this ensures `__all__` is used correctly.
if module_all or module_all_extra:
submod_name = None
submod = None
@@ -859,7 +875,7 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
pymodule2sphinx(basepath, submod_name_full, submod, "%s submodule" % module_name, ())
fw("\n")
del submod_ls
- # done writing submodules!
+ # Done writing sub-modules!
write_example_ref("", fw, module_name)
@@ -870,10 +886,10 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
continue
if key in module_all_extra:
continue
- # naughty, we also add getset's into PyStructs, this is not typical py but also not incorrect.
+ # Naughty! We also add `getset` to `PyStruct`, this is not typical Python but also not incorrect.
- # type_name is only used for examples and messages
- # "<class 'bpy.app.handlers'>" --> bpy.app.handlers
+ # `type_name` is only used for examples and messages:
+ # `<class 'bpy.app.handlers'>` -> `bpy.app.handlers`.
type_name = str(type(module)).strip("<>").split(" ", 1)[-1][1:-1]
if type(descr) == types.GetSetDescriptorType:
py_descr2sphinx("", fw, descr, module_name, type_name, key)
@@ -889,13 +905,13 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
value_type = type(value)
descr_sorted.append((key, descr, value, type(value)))
- # sort by the valye type
+ # Sort by the value type.
descr_sorted.sort(key=lambda descr_data: str(descr_data[3]))
for key, descr, value, value_type in descr_sorted:
if key in module_all_extra:
continue
- # must be documented as a submodule
+ # Must be documented as a sub-module.
if is_struct_seq(value):
continue
@@ -909,7 +925,7 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
classes = []
submodules = []
- # use this list so we can sort by type
+ # Use this list so we can sort by type.
module_dir_value_type = []
for attribute in module_dir:
@@ -919,7 +935,7 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
if attribute in attribute_set:
continue
- if attribute.startswith("n_"): # annoying exception, needed for bpy.app
+ if attribute.startswith("n_"): # Annoying exception, needed for `bpy.app`.
continue
# workaround for bpy.app documenting .index() and .count()
@@ -940,18 +956,18 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
if value_type == FunctionType:
pyfunc2sphinx("", fw, module_name, None, attribute, value, is_class=False)
- # both the same at the moment but to be future proof
+ # Both the same at the moment but to be future proof.
elif value_type in {types.BuiltinMethodType, types.BuiltinFunctionType}:
- # 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.
+ # NOTE: can't get args from these, so dump the string as is
+ # this means any module used like this must have fully formatted doc-strings.
py_c_func2sphinx("", fw, module_name, None, attribute, value, is_class=False)
elif value_type == type:
classes.append((attribute, value))
elif issubclass(value_type, types.ModuleType):
submodules.append((attribute, value))
elif issubclass(value_type, (bool, int, float, str, tuple)):
- # constant, not much fun we can do here except to list it.
- # TODO, figure out some way to document these!
+ # Constant, not much fun we can do here except to list it.
+ # TODO: figure out some way to document these!
fw(".. data:: %s\n\n" % attribute)
write_indented_lines(" ", fw, "Constant value %s" % repr(value), False)
fw("\n")
@@ -960,11 +976,11 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
continue
attribute_set.add(attribute)
- # TODO, more types...
+ # TODO: more types.
del module_dir_value_type
- # TODO, bpy_extras does this already, mathutils not.
- '''
+ # TODO: `bpy_extras` does this already, `mathutils` not.
+ """
if submodules:
fw("\n"
"**********\n"
@@ -975,12 +991,12 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
for attribute, submod in submodules:
fw("* :mod:`%s.%s`\n" % (module_name, attribute))
fw("\n")
- '''
+ """
if module_grouping is not None:
classes.sort(key=lambda pair: module_grouping_sort_key(pair[0]))
- # write collected classes now
+ # Write collected classes now.
for (type_name, value) in classes:
if module_grouping is not None:
@@ -988,7 +1004,7 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
if heading:
fw(title_string(heading, heading_char))
- # May need to be its own function
+ # May need to be its own function.
if value.__doc__:
if value.__doc__.startswith(".. class::"):
fw(value.__doc__)
@@ -1007,7 +1023,7 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
if type(descr) == ClassMethodDescriptorType:
py_descr2sphinx(" ", fw, descr, module_name, type_name, key)
- # needed for pure Python classes
+ # Needed for pure Python classes.
for key, descr in descr_items:
if type(descr) == FunctionType:
pyfunc2sphinx(" ", fw, module_name, type_name, key, descr, is_class=True)
@@ -1031,7 +1047,7 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
file.close()
-# Changes in Blender will force errors here
+# Changes In Blender will force errors here.
context_type_map = {
# context_member: (RNA type, is_collection)
"active_annotation_layer": ("GPencilLayer", False),
@@ -1140,7 +1156,7 @@ context_type_map = {
def pycontext2sphinx(basepath):
- # Only use once. very irregular
+ # Only use once. very irregular.
filepath = os.path.join(basepath, "bpy.context.rst")
file = open(filepath, "w", encoding="utf-8")
@@ -1161,8 +1177,8 @@ def pycontext2sphinx(basepath):
fw(title_string("Global Context", "-"))
fw("These properties are available in any contexts.\n\n")
- # very silly. could make these global and only access once.
- # structs, funcs, ops, props = rna_info.BuildRNAInfo()
+ # Very silly. could make these global and only access once:
+ # `structs, funcs, ops, props = rna_info.BuildRNAInfo()`.
structs, funcs, ops, props = rna_info_BuildRNAInfo_cache()
struct = structs[("", "Context")]
struct_blacklist = RNA_BLACKLIST.get(struct.identifier, ())
@@ -1171,7 +1187,7 @@ def pycontext2sphinx(basepath):
sorted_struct_properties = struct.properties[:]
sorted_struct_properties.sort(key=lambda prop: prop.identifier)
- # First write RNA
+ # First write RNA.
for prop in sorted_struct_properties:
# Support blacklisting props.
if prop.identifier in struct_blacklist:
@@ -1185,14 +1201,14 @@ def pycontext2sphinx(basepath):
if prop.description:
fw(" %s\n\n" % prop.description)
- # special exception, can't use generic code here for enums
+ # Special exception, can't use generic code here for enums.
if prop.type == "enum":
enum_text = pyrna_enum2sphinx(prop)
if enum_text:
write_indented_lines(" ", fw, enum_text)
fw("\n")
del enum_text
- # end enum exception
+ # End enum exception.
fw(" :type: %s\n\n" % type_descr)
@@ -1209,7 +1225,7 @@ def pycontext2sphinx(basepath):
unique_context_strings = set()
for ctx_str, ctx_members in sorted(context_member_map.items()):
subsection = "%s Context" % ctx_str.split("_")[0].title()
- fw("\n%s\n%s\n\n" % (subsection, (len(subsection) * '-')))
+ fw("\n%s\n%s\n\n" % (subsection, (len(subsection) * "-")))
for member in ctx_members:
unique_all_len = len(unique)
unique.add(member)
@@ -1231,7 +1247,7 @@ def pycontext2sphinx(basepath):
(member, __file__)) from None
fw(" :type: %s :class:`bpy.types.%s`\n\n" % ("sequence of " if is_seq else "", member_type))
- # generate typemap...
+ # Generate type-map:
# for member in sorted(unique_context_strings):
# print(' "%s": ("", False),' % member)
if len(context_type_map) > len(unique_context_strings):
@@ -1239,13 +1255,14 @@ def pycontext2sphinx(basepath):
"Some types are not used: %s" %
str([member for member in context_type_map if member not in unique_context_strings]))
else:
- pass # will have raised an error above
+ pass # Will have raised an error above.
file.close()
def pyrna_enum2sphinx(prop, use_empty_descriptions=False):
- """ write a bullet point list of enum + descriptions
+ """
+ Write a bullet point list of enum + descriptions.
"""
if use_empty_descriptions:
@@ -1272,13 +1289,14 @@ def pyrna_enum2sphinx(prop, use_empty_descriptions=False):
def pyrna2sphinx(basepath):
- """ bpy.types and bpy.ops
"""
- # structs, funcs, ops, props = rna_info.BuildRNAInfo()
+ ``bpy.types`` and ``bpy.ops``.
+ """
+ # `structs, funcs, ops, props = rna_info.BuildRNAInfo()`
structs, funcs, ops, props = rna_info_BuildRNAInfo_cache()
if USE_ONLY_BUILTIN_RNA_TYPES:
- # Ignore properties that use non 'bpy.types' properties.
+ # Ignore properties that use non `bpy.types` properties.
structs_blacklist = {
v.identifier for v in structs.values()
if v.module_name != "bpy.types"
@@ -1335,7 +1353,7 @@ def pyrna2sphinx(basepath):
if prop.name or prop.description:
fw(indent(", ".join(val for val in (prop.name, prop.description) if val), ident + " ") + "\n\n")
- # special exception, can't use generic code here for enums
+ # Special exception, can't use generic code here for enums.
if enum_text:
write_indented_lines(ident + " ", fw, enum_text)
fw("\n")
@@ -1415,22 +1433,22 @@ def pyrna2sphinx(basepath):
fw(" %s\n\n" % struct.description)
- # properties sorted in alphabetical order
+ # Properties sorted in alphabetical order.
sorted_struct_properties = struct.properties[:]
sorted_struct_properties.sort(key=lambda prop: prop.identifier)
- # support blacklisting props
+ # Support blacklisting props.
struct_blacklist = RNA_BLACKLIST.get(struct_id, ())
for prop in sorted_struct_properties:
- # support blacklisting props
+ # Support blacklisting props.
if prop.identifier in struct_blacklist:
continue
type_descr = prop.get_type_description(class_fmt=":class:`%s`", collection_id=_BPY_PROP_COLLECTION_ID)
- # readonly properties use "data" directive, variables properties use "attribute" directive
- if 'readonly' in type_descr:
+ # Read-only properties use "data" directive, variables properties use "attribute" directive.
+ if "readonly" in type_descr:
fw(" .. data:: %s\n\n" % prop.identifier)
else:
fw(" .. attribute:: %s\n\n" % prop.identifier)
@@ -1438,18 +1456,18 @@ def pyrna2sphinx(basepath):
write_indented_lines(" ", fw, prop.description, False)
fw("\n")
- # special exception, can't use generic code here for enums
+ # Special exception, can't use generic code here for enums.
if prop.type == "enum":
enum_text = pyrna_enum2sphinx(prop)
if enum_text:
write_indented_lines(" ", fw, enum_text)
fw("\n")
del enum_text
- # end enum exception
+ # End enum exception.
fw(" :type: %s\n\n" % type_descr)
- # Python attributes
+ # Python attributes.
py_properties = struct.get_py_properties()
py_prop = None
for identifier, py_prop in py_properties:
@@ -1474,17 +1492,17 @@ def pyrna2sphinx(basepath):
if len(func.return_values) == 1:
write_param(" ", fw, func.return_values[0], is_return=True)
- elif func.return_values: # multiple return values
+ elif func.return_values: # Multiple return values.
fw(" :return (%s):\n" % ", ".join(prop.identifier for prop in func.return_values))
for prop in func.return_values:
- # TODO, pyrna_enum2sphinx for multiple return values... actually don't
- # think we even use this but still!!!
+ # TODO: pyrna_enum2sphinx for multiple return values... actually don't
+ # think we even use this but still!
type_descr = prop.get_type_description(
as_ret=True, class_fmt=":class:`%s`", collection_id=_BPY_PROP_COLLECTION_ID)
descr = prop.description
if not descr:
descr = prop.name
- # In rare cases descr may be empty
+ # In rare cases `descr` may be empty.
fw(" `%s`, %s\n\n" %
(prop.identifier,
", ".join((val for val in (descr, type_descr) if val))))
@@ -1493,7 +1511,7 @@ def pyrna2sphinx(basepath):
fw("\n")
- # Python methods
+ # Python methods.
py_funcs = struct.get_py_functions()
py_func = None
@@ -1512,7 +1530,7 @@ def pyrna2sphinx(basepath):
if struct.base or _BPY_STRUCT_FAKE:
bases = list(reversed(struct.get_bases()))
- # props
+ # Properties.
del lines[:]
if _BPY_STRUCT_FAKE:
@@ -1543,7 +1561,7 @@ def pyrna2sphinx(basepath):
fw(line)
fw("\n")
- # funcs
+ # Functions.
del lines[:]
if _BPY_STRUCT_FAKE:
@@ -1598,7 +1616,7 @@ def pyrna2sphinx(basepath):
if "bpy.types" not in EXCLUDE_MODULES:
for struct in structs.values():
- # TODO, rna_info should filter these out!
+ # TODO: rna_info should filter these out!
if "_OT_" in struct.identifier:
continue
write_struct(struct)
@@ -1633,7 +1651,7 @@ def pyrna2sphinx(basepath):
]
for key, descr in descr_items:
- # GetSetDescriptorType, GetSetDescriptorType's are not documented yet
+ # `GetSetDescriptorType`, `GetSetDescriptorType` types are not documented yet.
if type(descr) == MethodDescriptorType:
py_descr2sphinx(" ", fw, descr, "bpy.types", class_name, key)
@@ -1688,7 +1706,7 @@ def pyrna2sphinx(basepath):
# if the description isn't valid, we output the standard warning
# with a link to the wiki so that people can help
if not op.description or op.description == "(undocumented operator)":
- operator_description = undocumented_message('bpy.ops', op.module_name, op.func_name)
+ operator_description = undocumented_message("bpy.ops", op.module_name, op.func_name)
else:
operator_description = op.description
@@ -1717,9 +1735,9 @@ def pyrna2sphinx(basepath):
def write_sphinx_conf_py(basepath):
- '''
- Write sphinx's conf.py
- '''
+ """
+ Write sphinx's ``conf.py``.
+ """
filepath = os.path.join(basepath, "conf.py")
file = open(filepath, "w", encoding="utf-8")
fw = file.write
@@ -1816,9 +1834,9 @@ def execfile(filepath):
def write_rst_index(basepath):
- '''
- Write the rst file of the main page, needed for sphinx (index.html)
- '''
+ """
+ Write the RST file of the main page, needed for sphinx: ``index.html``.
+ """
filepath = os.path.join(basepath, "index.rst")
file = open(filepath, "w", encoding="utf-8")
fw = file.write
@@ -1896,7 +1914,7 @@ def write_rst_index(basepath):
fw("* :ref:`genindex`\n")
fw("* :ref:`modindex`\n\n")
- # special case, this 'bmesh.ops.rst' is extracted from C source
+ # Special case, this `bmesh.ops.rst` is extracted from C source.
if "bmesh.ops" not in EXCLUDE_MODULES:
execfile(os.path.join(SCRIPT_DIR, "rst_from_bmesh_opdefines.py"))
@@ -1904,9 +1922,9 @@ def write_rst_index(basepath):
def write_rst_bpy(basepath):
- '''
- Write rst file of bpy module (disabled by default)
- '''
+ """
+ Write RST file of ``bpy`` module (disabled by default)
+ """
if ARGS.bpy:
filepath = os.path.join(basepath, "bpy.rst")
file = open(filepath, "w", encoding="utf-8")
@@ -1923,9 +1941,9 @@ def write_rst_bpy(basepath):
def write_rst_types_index(basepath):
- '''
- Write the rst file of bpy.types module (index)
- '''
+ """
+ Write the RST file of ``bpy.types`` module (index)
+ """
if "bpy.types" not in EXCLUDE_MODULES:
filepath = os.path.join(basepath, "bpy.types.rst")
file = open(filepath, "w", encoding="utf-8")
@@ -1939,9 +1957,9 @@ def write_rst_types_index(basepath):
def write_rst_ops_index(basepath):
- '''
- Write the rst file of bpy.ops module (index)
- '''
+ """
+ Write the RST file of bpy.ops module (index)
+ """
if "bpy.ops" not in EXCLUDE_MODULES:
filepath = os.path.join(basepath, "bpy.ops.rst")
file = open(filepath, "w", encoding="utf-8")
@@ -1958,7 +1976,7 @@ def write_rst_ops_index(basepath):
def write_rst_msgbus(basepath):
"""
- Write the rst files of bpy.msgbus module
+ Write the RST files of ``bpy.msgbus`` module
"""
if 'bpy.msgbus' in EXCLUDE_MODULES:
return
@@ -1980,12 +1998,11 @@ def write_rst_msgbus(basepath):
def write_rst_data(basepath):
- '''
- Write the rst file of bpy.data module
- '''
+ """
+ Write the RST file of ``bpy.data`` module.
+ """
if "bpy.data" not in EXCLUDE_MODULES:
- # not actually a module, only write this file so we
- # can reference in the TOC
+ # Not actually a module, only write this file so we can reference in the TOC.
filepath = os.path.join(basepath, "bpy.data.rst")
file = open(filepath, "w", encoding="utf-8")
fw = file.write
@@ -2007,9 +2024,9 @@ def write_rst_data(basepath):
def write_rst_importable_modules(basepath):
- '''
- Write the rst files of importable modules
- '''
+ """
+ Write the RST files of importable modules.
+ """
importable_modules = {
# Python_modules
"bpy.path": "Path Utilities",
@@ -2088,12 +2105,12 @@ def write_rst_importable_modules(basepath):
def copy_handwritten_rsts(basepath):
- # info docs
+ # Info docs.
if not EXCLUDE_INFO_DOCS:
for info, info_desc in INFO_DOCS:
shutil.copy2(os.path.join(RST_DIR, info), basepath)
- # TODO put this docs in Blender's code and use import as per modules above
+ # TODO: put this docs in Blender's code and use import as per modules above.
handwritten_modules = [
"bgl", # "Blender OpenGl wrapper"
"bmesh.ops", # generated by rst_from_bmesh_opdefines.py
@@ -2104,13 +2121,13 @@ def copy_handwritten_rsts(basepath):
for mod_name in handwritten_modules:
if mod_name not in EXCLUDE_MODULES:
- # copy2 keeps time/date stamps
+ # Copy2 keeps time/date stamps.
shutil.copy2(os.path.join(RST_DIR, "%s.rst" % mod_name), basepath)
- # changelog
+ # Change-log.
shutil.copy2(os.path.join(RST_DIR, "change_log.rst"), basepath)
- # copy images, could be smarter but just glob for now.
+ # Copy images, could be smarter but just glob for now.
for f in os.listdir(RST_DIR):
if f.endswith(".png"):
shutil.copy2(os.path.join(RST_DIR, f), basepath)
@@ -2132,12 +2149,16 @@ def copy_handwritten_extra(basepath):
def copy_theme_assets(basepath):
- shutil.copytree(os.path.join(SCRIPT_DIR, "static"),
- os.path.join(basepath, "static"),
- copy_function=shutil.copy)
- shutil.copytree(os.path.join(SCRIPT_DIR, "templates"),
- os.path.join(basepath, "templates"),
- copy_function=shutil.copy)
+ shutil.copytree(
+ os.path.join(SCRIPT_DIR, "static"),
+ os.path.join(basepath, "static"),
+ copy_function=shutil.copy,
+ )
+ shutil.copytree(
+ os.path.join(SCRIPT_DIR, "templates"),
+ os.path.join(basepath, "templates"),
+ copy_function=shutil.copy,
+ )
def rna2sphinx(basepath):
@@ -2177,18 +2198,18 @@ def rna2sphinx(basepath):
def align_sphinx_in_to_sphinx_in_tmp(dir_src, dir_dst):
- '''
+ """
Move changed files from SPHINX_IN_TMP to SPHINX_IN
- '''
+ """
import filecmp
- # possible the dir doesn't exist when running recursively
+ # Possible the dir doesn't exist when running recursively.
os.makedirs(dir_dst, exist_ok=True)
sphinx_dst_files = set(os.listdir(dir_dst))
sphinx_src_files = set(os.listdir(dir_src))
- # remove deprecated files that have been removed
+ # Remove deprecated files that have been removed.
for f in sorted(sphinx_dst_files):
if f not in sphinx_src_files:
BPY_LOGGER.debug("\tdeprecated: %s" % f)
@@ -2270,55 +2291,59 @@ def main():
# Perform changes to Blender itself.
setup_data = setup_blender()
- # eventually, create the dirs
+ # Eventually, create the directories.
for dir_path in [ARGS.output_dir, SPHINX_IN]:
if not os.path.exists(dir_path):
os.mkdir(dir_path)
- # eventually, log in files
+ # Eventually, log in files.
if ARGS.log:
bpy_logfile = os.path.join(ARGS.output_dir, ".bpy.log")
bpy_logfilehandler = logging.FileHandler(bpy_logfile, mode="w")
bpy_logfilehandler.setLevel(logging.DEBUG)
BPY_LOGGER.addHandler(bpy_logfilehandler)
- # using a FileHandler seems to disable the stdout, so we add a StreamHandler
+ # using a `FileHandler` seems to disable the `stdout`, so we add a `StreamHandler`.
bpy_log_stdout_handler = logging.StreamHandler(stream=sys.stdout)
bpy_log_stdout_handler.setLevel(logging.DEBUG)
BPY_LOGGER.addHandler(bpy_log_stdout_handler)
- # in case of out-of-source build, copy the needed dirs
+ # In case of out-of-source build, copy the needed directories.
if ARGS.output_dir != SCRIPT_DIR:
- # examples dir
+ # Examples directory.
examples_dir_copy = os.path.join(ARGS.output_dir, "examples")
if os.path.exists(examples_dir_copy):
shutil.rmtree(examples_dir_copy, True)
- shutil.copytree(EXAMPLES_DIR,
- examples_dir_copy,
- ignore=shutil.ignore_patterns(*(".svn",)),
- copy_function=shutil.copy)
-
- # dump the api in rst files
+ shutil.copytree(
+ EXAMPLES_DIR,
+ examples_dir_copy,
+ ignore=shutil.ignore_patterns(*(".svn",)),
+ copy_function=shutil.copy,
+ )
+
+ # Dump the API in RST files.
if os.path.exists(SPHINX_IN_TMP):
shutil.rmtree(SPHINX_IN_TMP, True)
rna2sphinx(SPHINX_IN_TMP)
if ARGS.full_rebuild:
- # only for full updates
+ # Only for full updates.
shutil.rmtree(SPHINX_IN, True)
- shutil.copytree(SPHINX_IN_TMP,
- SPHINX_IN,
- copy_function=shutil.copy)
+ shutil.copytree(
+ SPHINX_IN_TMP,
+ SPHINX_IN,
+ copy_function=shutil.copy,
+ )
if ARGS.sphinx_build and os.path.exists(SPHINX_OUT):
shutil.rmtree(SPHINX_OUT, True)
if ARGS.sphinx_build_pdf and os.path.exists(SPHINX_OUT_PDF):
shutil.rmtree(SPHINX_OUT_PDF, True)
else:
- # move changed files in SPHINX_IN
+ # Move changed files in `SPHINX_IN`.
align_sphinx_in_to_sphinx_in_tmp(SPHINX_IN_TMP, SPHINX_IN)
- # report which example files weren't used
+ # Report which example files weren't used.
EXAMPLE_SET_UNUSED = EXAMPLE_SET - EXAMPLE_SET_USED
if EXAMPLE_SET_UNUSED:
BPY_LOGGER.debug("\nUnused examples found in '%s'..." % EXAMPLES_DIR)
@@ -2326,53 +2351,59 @@ def main():
BPY_LOGGER.debug(" %s.py" % f)
BPY_LOGGER.debug(" %d total\n" % len(EXAMPLE_SET_UNUSED))
- # eventually, build the html docs
+ # Eventually, build the html docs.
if ARGS.sphinx_build:
import subprocess
subprocess.call(SPHINX_BUILD)
- # sphinx-build log cleanup+sort
+ # Sphinx-build log cleanup+sort.
if ARGS.log:
if os.stat(SPHINX_BUILD_LOG).st_size:
refactor_sphinx_log(SPHINX_BUILD_LOG)
- # eventually, build the pdf docs
+ # Eventually, build the PDF docs.
if ARGS.sphinx_build_pdf:
import subprocess
subprocess.call(SPHINX_BUILD_PDF)
subprocess.call(SPHINX_MAKE_PDF, stdout=SPHINX_MAKE_PDF_STDOUT)
- # sphinx-build log cleanup+sort
+ # Sphinx-build log cleanup+sort.
if ARGS.log:
if os.stat(SPHINX_BUILD_PDF_LOG).st_size:
refactor_sphinx_log(SPHINX_BUILD_PDF_LOG)
- # eventually, prepare the dir to be deployed online (REFERENCE_PATH)
+ # Eventually, prepare the dir to be deployed online (REFERENCE_PATH).
if ARGS.pack_reference:
if ARGS.sphinx_build:
- # delete REFERENCE_PATH
+ # Delete REFERENCE_PATH.
if os.path.exists(REFERENCE_PATH):
shutil.rmtree(REFERENCE_PATH, True)
- # copy SPHINX_OUT to the REFERENCE_PATH
- ignores = ('.doctrees', '.buildinfo')
- shutil.copytree(SPHINX_OUT,
- REFERENCE_PATH,
- ignore=shutil.ignore_patterns(*ignores))
+ # Copy SPHINX_OUT to the REFERENCE_PATH.
+ ignores = (".doctrees", ".buildinfo")
+ shutil.copytree(
+ SPHINX_OUT,
+ REFERENCE_PATH,
+ ignore=shutil.ignore_patterns(*ignores),
+ )
- # zip REFERENCE_PATH
+ # Zip REFERENCE_PATH.
basename = os.path.join(ARGS.output_dir, REFERENCE_NAME)
- tmp_path = shutil.make_archive(basename, 'zip',
- root_dir=ARGS.output_dir,
- base_dir=REFERENCE_NAME)
+ tmp_path = shutil.make_archive(
+ basename, "zip",
+ root_dir=ARGS.output_dir,
+ base_dir=REFERENCE_NAME,
+ )
final_path = os.path.join(REFERENCE_PATH, BLENDER_ZIP_FILENAME)
os.rename(tmp_path, final_path)
if ARGS.sphinx_build_pdf:
- # copy the pdf to REFERENCE_PATH
- shutil.copy(os.path.join(SPHINX_OUT_PDF, "contents.pdf"),
- os.path.join(REFERENCE_PATH, BLENDER_PDF_FILENAME))
+ # Copy the pdf to REFERENCE_PATH.
+ shutil.copy(
+ os.path.join(SPHINX_OUT_PDF, "contents.pdf"),
+ os.path.join(REFERENCE_PATH, BLENDER_PDF_FILENAME),
+ )
teardown_blender(setup_data)