1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
21 # run this script in the game engine.
22 # or on the command line with...
23 # ./blender.bin --background -noaudio --python source/tests/bl_rst_completeness.py
25 # Paste this into the bge and run on an always actuator.
27 filepath = "/dsk/data/src/blender/blender/source/tests/bl_rst_completeness.py"
28 exec(compile(open(filepath).read(), filepath, 'exec'))
33 THIS_DIR = os.path.dirname(__file__)
34 RST_DIR = os.path.normpath(os.path.join(THIS_DIR, "..", "..", "doc", "python_api", "rst"))
37 sys.path.append(THIS_DIR)
39 import rst_to_doctree_mini
48 ("bge.constraints.rst", "bge.constraints", False),
49 ("bge.events.rst", "bge.events", False),
50 ("bge.logic.rst", "bge.logic", False),
51 ("bge.render.rst", "bge.render", False),
52 ("bge.texture.rst", "bge.texture", False),
53 ("bge.types.rst", "bge.types", False),
55 ("bgl.rst", "bgl", True),
56 ("gpu.rst", "gpu", False),
59 def is_directive_pydata(filepath, directive):
60 if directive.type in {"function", "method", "class", "attribute", "data"}:
62 elif directive.type in {"module", "note", "warning", "code-block", "hlist", "seealso"}:
64 elif directive.type in {"literalinclude"}: # TODO
67 print(directive_to_str(filepath, directive), end=" ")
68 print("unknown directive type %r" % directive.type)
72 def directive_to_str(filepath, directive):
73 return "%s:%d:%d:" % (filepath, directive.line + 1, directive.indent)
76 def directive_members_dict(filepath, directive_members):
77 return {directive.value_strip: directive for directive in directive_members
78 if is_directive_pydata(filepath, directive)}
81 def module_validate(filepath, mod, mod_name, doctree, partial_ok):
82 # RST member missing from MODULE ???
83 for directive in doctree:
84 # print(directive.type)
85 if is_directive_pydata(filepath, directive):
86 attr = directive.value_strip
87 has_attr = hasattr(mod, attr)
90 # so we can have glNormal docs cover glNormal3f
93 if s.startswith(attr):
98 print(directive_to_str(filepath, directive), end=" ")
99 print("rst contains non existing member %r" % attr)
101 # if its a class, scan down the class...
102 # print(directive.type)
104 if directive.type == "class":
105 cls = getattr(mod, attr)
106 # print("directive: ", directive)
107 for directive_child in directive.members:
108 # print("directive_child: ", directive_child)
109 if is_directive_pydata(filepath, directive_child):
110 attr_child = directive_child.value_strip
111 if attr_child not in cls.__dict__:
112 attr_id = "%s.%s" % (attr, attr_child)
113 print(directive_to_str(filepath, directive_child), end=" ")
114 print("rst contains non existing class member %r" % attr_id)
117 # MODULE member missing from RST ???
118 doctree_dict = directive_members_dict(filepath, doctree)
119 for attr in dir(mod):
120 if attr.startswith("_"):
123 directive = doctree_dict.get(attr)
124 if directive is None:
125 print("module contains undocumented member %r from %r" % ("%s.%s" % (mod_name, attr), filepath))
127 if directive.type == "class":
128 directive_dict = directive_members_dict(filepath, directive.members)
129 cls = getattr(mod, attr)
130 for attr_child in cls.__dict__.keys():
131 if attr_child.startswith("_"):
133 if attr_child not in directive_dict:
134 attr_id = "%s.%s.%s" % (mod_name, attr, attr_child), filepath
135 print("module contains undocumented member %r from %r" % attr_id)
141 print("Skipping BGE modules!")
143 for filename, modname, partial_ok in modules:
144 if bge is None and modname.startswith("bge"):
147 filepath = os.path.join(RST_DIR, filename)
148 if not os.path.exists(filepath):
149 raise Exception("%r not found" % filepath)
151 doctree = rst_to_doctree_mini.parse_rst_py(filepath)
153 mod = sys.modules[modname]
155 module_validate(filepath, mod, modname, doctree, partial_ok)
158 if __name__ == "__main__":