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),
60
def is_directive_pydata(filepath, directive):
61
if directive.type in {"function", "method", "class", "attribute", "data"}:
63
elif directive.type in {"module", "note", "warning", "code-block", "hlist", "seealso"}:
65
elif directive.type in {"literalinclude"}: # TODO
68
print(directive_to_str(filepath, directive), end=" ")
69
print("unknown directive type %r" % directive.type)
73
def directive_to_str(filepath, directive):
74
return "%s:%d:%d:" % (filepath, directive.line + 1, directive.indent)
77
def directive_members_dict(filepath, directive_members):
78
return {directive.value_strip: directive for directive in directive_members
79
if is_directive_pydata(filepath, directive)}
82
def module_validate(filepath, mod, mod_name, doctree, partial_ok):
83
# RST member missing from MODULE ???
84
for directive in doctree:
85
# print(directive.type)
86
if is_directive_pydata(filepath, directive):
87
attr = directive.value_strip
88
has_attr = hasattr(mod, attr)
91
# so we can have glNormal docs cover glNormal3f
94
if s.startswith(attr):
99
print(directive_to_str(filepath, directive), end=" ")
100
print("rst contains non existing member %r" % attr)
102
# if its a class, scan down the class...
103
# print(directive.type)
105
if directive.type == "class":
106
cls = getattr(mod, attr)
107
# print("directive: ", directive)
108
for directive_child in directive.members:
109
# print("directive_child: ", directive_child)
110
if is_directive_pydata(filepath, directive_child):
111
attr_child = directive_child.value_strip
112
if attr_child not in cls.__dict__:
113
attr_id = "%s.%s" % (attr, attr_child)
114
print(directive_to_str(filepath, directive_child), end=" ")
115
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__":