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
diff options
context:
space:
mode:
-rw-r--r--release/scripts/modules/bpy/app.py21
-rw-r--r--release/scripts/modules/bpy/utils.py54
-rw-r--r--source/blender/python/intern/bpy_props.c60
-rw-r--r--source/blender/python/sphinx_doc_gen.py147
4 files changed, 234 insertions, 48 deletions
diff --git a/release/scripts/modules/bpy/app.py b/release/scripts/modules/bpy/app.py
index da45ab8eb30..8fc92175d0e 100644
--- a/release/scripts/modules/bpy/app.py
+++ b/release/scripts/modules/bpy/app.py
@@ -18,6 +18,27 @@
# <pep8 compliant>
+"""
+This module contains application values that remain unchanged during runtime.
+
+.. data:: version
+
+ The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)
+
+
+.. data:: version_string
+
+ The Blender version formatted as a string.
+
+.. data:: home
+
+ The blender home directory, normally matching $HOME
+
+.. data:: binary_path
+
+ The location of blenders executable, useful for utilities that spawn new instances.
+
+"""
# constants
import _bpy
version = _bpy._VERSION
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 1948a28a726..90ba9ba4c71 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -18,13 +18,18 @@
# <pep8 compliant>
-import bpy
-import os
+"""
+This module contains utility functions spesific to blender but
+not assosiated with blenders internal data.
+"""
+
+import bpy as _bpy
+import os as _os
def expandpath(path):
if path.startswith("//"):
- return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
+ return _os.path.join(_os.path.dirname(_bpy.data.filename), path[2:])
return path
@@ -47,21 +52,23 @@ _unclean_chars = ''.join([chr(i) for i in _unclean_chars])
def clean_name(name, replace="_"):
- '''
+ """
+ Returns a name with characters replaced that may cause problems under various circumstances, such as writing to a file.
All characters besides A-Z/a-z, 0-9 are replaced with "_"
or the replace argumet if defined.
- '''
+ """
for ch in _unclean_chars:
name = name.replace(ch, replace)
return name
def display_name(name):
- '''
- Only capitalize all lowercase names, mixed case use them as is.
- should work with filenames and module names.
- '''
- name_base = os.path.splitext(name)[0]
+ """
+ Creates a display string from name to be used menus and the user interface.
+ Capitalize the first letter in all lowercase names, mixed case names are kept as is.
+ Intended for use with filenames and module names.
+ """
+ name_base = _os.path.splitext(name)[0]
# string replacements
name_base = name_base.replace("_colon_", ":")
@@ -75,39 +82,44 @@ def display_name(name):
# base scripts
-_scripts = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)
-_scripts = (os.path.normpath(_scripts), )
+_scripts = _os.path.join(_os.path.dirname(__file__), _os.path.pardir, _os.path.pardir)
+_scripts = (_os.path.normpath(_scripts), )
def script_paths(*args):
+ """
+ Returns a list of valid script paths from the home directory and user preferences.
+
+ Accepts any number of string arguments which are joined to make a path.
+ """
scripts = list(_scripts)
# add user scripts dir
- user_script_path = bpy.context.user_preferences.filepaths.python_scripts_directory
+ user_script_path = _bpy.context.user_preferences.filepaths.python_scripts_directory
if not user_script_path:
# XXX - WIN32 needs checking, perhaps better call a blender internal function.
- user_script_path = os.path.join(os.path.expanduser("~"), ".blender", "scripts")
+ user_script_path = _os.path.join(_os.path.expanduser("~"), ".blender", "scripts")
- user_script_path = os.path.normpath(user_script_path)
+ user_script_path = _os.path.normpath(user_script_path)
- if user_script_path not in scripts and os.path.isdir(user_script_path):
+ if user_script_path not in scripts and _os.path.isdir(user_script_path):
scripts.append(user_script_path)
if not args:
return scripts
- subdir = os.path.join(*args)
+ subdir = _os.path.join(*args)
script_paths = []
for path in scripts:
- path_subdir = os.path.join(path, subdir)
- if os.path.isdir(path_subdir):
+ path_subdir = _os.path.join(path, subdir)
+ if _os.path.isdir(path_subdir):
script_paths.append(path_subdir)
return script_paths
-_presets = os.path.join(_scripts[0], "presets") # FIXME - multiple paths
+_presets = _os.path.join(_scripts[0], "presets") # FIXME - multiple paths
def preset_paths(subdir):
@@ -115,4 +127,4 @@ def preset_paths(subdir):
Returns a list of paths for a spesific preset.
'''
- return (os.path.join(_presets, subdir), )
+ return (_os.path.join(_presets, subdir), )
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 938aaca4b9a..946e94c7064 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -46,6 +46,10 @@ static PyObject *bpy_prop_deferred_return(void *func, PyObject *kw)
/* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna allong
* This isnt incorrect since its a python object - but be careful */
+static char BPy_BoolProperty_doc[] =
+".. function:: BoolProperty(name=\"\", description=\"\", default=False, hidden=False)\n"
+"\n"
+" Returns a new boolean property definition..";
PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -79,6 +83,10 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
}
}
+static char BPy_IntProperty_doc[] =
+".. function:: IntProperty(name=\"\", description=\"\", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, hidden=False)\n"
+"\n"
+" Returns a new int property definition.";
PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -113,6 +121,10 @@ PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
}
}
+static char BPy_FloatProperty_doc[] =
+".. function:: FloatProperty(name=\"\", description=\"\", default=0.0, min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, hidden=False)\n"
+"\n"
+" Returns a new float property definition.";
PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -147,6 +159,10 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
}
}
+static char BPy_FloatVectorProperty_doc[] =
+".. function:: FloatVectorProperty(name=\"\", description=\"\", default=(0.0, 0.0, 0.0), min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, hidden=False, size=3)\n"
+"\n"
+" Returns a new vector float property definition.";
PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -213,6 +229,10 @@ PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
}
}
+static char BPy_StringProperty_doc[] =
+".. function:: StringProperty(name=\"\", description=\"\", default=\"\", maxlen=0, hidden=False)\n"
+"\n"
+" Returns a new string property definition.";
PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -291,6 +311,13 @@ static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, in
return items;
}
+static char BPy_EnumProperty_doc[] =
+".. function:: EnumProperty(items, name=\"\", description=\"\", default=\"\", hidden=False)\n"
+"\n"
+" Returns a new enumerator property definition.\n"
+"\n"
+" :arg items: The items that make up this enumerator.\n"
+" :type items: sequence of string triplets";
PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -349,6 +376,13 @@ static StructRNA *pointer_type_from_py(PyObject *value)
return srna;
}
+static char BPy_PointerProperty_doc[] =
+".. function:: PointerProperty(items, type=\"\", description=\"\", default=\"\", hidden=False)\n"
+"\n"
+" Returns a new pointer property definition.\n"
+"\n"
+" :arg type: Dynamic type from :mod:`bpy.types`.\n"
+" :type type: class";
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -388,6 +422,13 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
+static char BPy_CollectionProperty_doc[] =
+".. function:: CollectionProperty(items, type=\"\", description=\"\", default=\"\", hidden=False)\n"
+"\n"
+" Returns a new collection property definition.\n"
+"\n"
+" :arg type: Dynamic type from :mod:`bpy.types`.\n"
+" :type type: class";
PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -428,21 +469,22 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
}
static struct PyMethodDef props_methods[] = {
- {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
- {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
- {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
- {"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS, ""},
- {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
- {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""},
- {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""},
- {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""},
+ {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc},
+ {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntProperty_doc},
+ {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatProperty_doc},
+ {"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatVectorProperty_doc},
+ {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, BPy_StringProperty_doc},
+ {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, BPy_EnumProperty_doc},
+ {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, BPy_PointerProperty_doc},
+ {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, BPy_CollectionProperty_doc},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef props_module = {
PyModuleDef_HEAD_INIT,
"bpy.props",
- "",
+ "This module defines properties to extend blenders internal data, the result of these functions"
+ " is used to assign properties to classes registered with blender and can't be used directly.",
-1,/* multiple "initialization" just copies the module dict. */
props_methods,
NULL, NULL, NULL, NULL
diff --git a/source/blender/python/sphinx_doc_gen.py b/source/blender/python/sphinx_doc_gen.py
index ec17139b843..a882e145aec 100644
--- a/source/blender/python/sphinx_doc_gen.py
+++ b/source/blender/python/sphinx_doc_gen.py
@@ -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: