gen_doc.py 8.0 KB
Newer Older
W
Wang,Jeff 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
import argparse
import sys
import types
Z
Zeng Jinle 已提交
19 20
import os
import contextlib
D
dongdaxiang 已提交
21
import paddle as paddle
W
Wang,Jeff 已提交
22
import paddle.fluid as fluid
23
import paddle.tensor as tensor
24
import paddle.nn as nn
M
MRXLT 已提交
25 26
import paddle.optimizer as optimizer

D
dongdaxiang 已提交
27 28
import paddle.distributed.fleet as fleet
import paddle.distributed as distributed
M
MRXLT 已提交
29
#import paddle.complex as complex
30
#import paddle.framework as framework
W
Wang,Jeff 已提交
31

M
MRXLT 已提交
32

W
Wang,Jeff 已提交
33 34 35 36
def parse_arg():
    parser = argparse.ArgumentParser()
    parser.add_argument('--submodules', nargs="*")
    parser.add_argument(
M
MRXLT 已提交
37 38 39
        '--module_name',
        type=str,
        help='Generate the documentation of which module')
Z
Zeng Jinle 已提交
40 41
    parser.add_argument(
        '--module_prefix', type=str, help='Generate the prefix of module')
Z
Zeng Jinle 已提交
42
    parser.add_argument(
M
MRXLT 已提交
43 44 45
        '--output',
        type=str,
        help='Output file or output directory for output rst')
46
    parser.add_argument(
M
MRXLT 已提交
47 48 49
        '--output_name',
        type=str,
        help='Output file or output directory for output rst')
50
    parser.add_argument(
M
MRXLT 已提交
51 52 53
        '--output_dir',
        type=str,
        help='Output file or output directory for output rst')
Z
Zeng Jinle 已提交
54
    parser.add_argument(
M
MRXLT 已提交
55 56 57 58
        '--to_multiple_files',
        type=bool,
        default=False,
        help='Whether to separate to multiple files')
59

W
Wang,Jeff 已提交
60 61
    return parser.parse_args()

Z
Zeng Jinle 已提交
62 63 64 65 66 67 68 69
    def print_item(self, name):
        item = getattr(self.module, name, None)
        if item is None:
            return
        if isinstance(item, types.TypeType):
            self.print_class(name)
        elif isinstance(item, types.FunctionType):
            self.print_method(name)
W
Wang,Jeff 已提交
70
        else:
Z
Zeng Jinle 已提交
71
            pass
W
Wang,Jeff 已提交
72

M
MRXLT 已提交
73

Z
Zeng Jinle 已提交
74
class DocGenerator(object):
M
MRXLT 已提交
75
    def __init__(self, module_name=None, module_prefix=None):
Z
Zeng Jinle 已提交
76 77 78 79 80 81 82
        self.module_name = module_name
        self.module_prefix = module_prefix
        self.stream = None

    @contextlib.contextmanager
    def guard(self, filename):
        assert self.stream is None, "stream must be None"
M
MRXLT 已提交
83
        self.stream = open(filename, 'w')
Z
Zeng Jinle 已提交
84 85 86
        yield
        self.stream.close()
        self.stream = None
W
Wang,Jeff 已提交
87 88 89 90

    def print_submodule(self, submodule_name):
        submodule = getattr(self.module, submodule_name)
        if submodule is None:
M
MRXLT 已提交
91 92
            raise ValueError(
                "Cannot find submodule {0}".format(submodule_name))
W
Wang,Jeff 已提交
93 94
        self.print_section(submodule_name)

M
MRXLT 已提交
95
        for item in sorted(submodule.__all__, key=str.lower):
W
Wang,Jeff 已提交
96 97 98
            self.print_item(item)

    def print_current_module(self):
M
MRXLT 已提交
99
        for item in sorted(self.module.__all__, key=str.lower):
W
Wang,Jeff 已提交
100 101 102 103 104
            self.print_item(item)

    def print_section(self, name):
        self._print_header_(name, dot='=', is_title=False)

T
tianshuo78520a 已提交
105
    def print_item(self, name, output_name):
W
Wang,Jeff 已提交
106 107 108 109 110 111
        item = getattr(self.module, name, None)
        if isinstance(item, types.TypeType):
            self.print_class(name)
        elif isinstance(item, types.FunctionType):
            self.print_method(name)
        else:
T
tianshuo78520a 已提交
112
            self.stream.close()
M
MRXLT 已提交
113
            path = os.getcwd() + "/" + output_name + "/" + name + ".rst"
Y
Yucheng 已提交
114 115
            if name != "PipeReader":
                os.remove(path)
W
Wang,Jeff 已提交
116 117 118 119

    def print_class(self, name):
        self._print_ref_(name)
        self._print_header_(name, dot='-', is_title=False)
L
lujun 已提交
120 121 122 123 124
        if "fluid.dygraph" in self.module_prefix:
            self.stream.write('''..  autoclass:: paddle.{0}.{1}
    :members:
    :noindex:

125 126 127 128 129 130 131 132
'''.format(self.module_prefix, name))
        elif "fluid.optimizer" in self.module_prefix:
            self.stream.write('''..  autoclass:: paddle.{0}.{1}
    :members:
    :inherited-members:
    :exclude-members: apply_gradients, apply_optimize, backward, load
    :noindex:

L
lujun 已提交
133 134 135
'''.format(self.module_prefix, name))
        else:
            self.stream.write('''..  autoclass:: paddle.{0}.{1}
W
Wang,Jeff 已提交
136
    :members:
137
    :inherited-members:
W
Wang,Jeff 已提交
138 139
    :noindex:

Z
Zeng Jinle 已提交
140
'''.format(self.module_prefix, name))
W
Wang,Jeff 已提交
141 142 143 144 145 146 147

    def print_method(self, name):
        self._print_ref_(name)
        self._print_header_(name, dot='-', is_title=False)
        self.stream.write('''..  autofunction:: paddle.{0}.{1}
    :noindex:

Z
Zeng Jinle 已提交
148
'''.format(self.module_prefix, name))
W
Wang,Jeff 已提交
149

Z
Zeng Jinle 已提交
150 151 152 153 154 155
    def print_header_reminder(self):
        self.stream.write('''..  THIS FILE IS GENERATED BY `gen_doc.{py|sh}`
    !DO NOT EDIT THIS FILE MANUALLY!

''')

W
Wang,Jeff 已提交
156 157 158 159 160 161 162 163 164 165 166 167 168
    def _print_header_(self, name, dot, is_title):
        dot_line = dot * len(name)
        if is_title:
            self.stream.write(dot_line)
            self.stream.write('\n')
        self.stream.write(name)
        self.stream.write('\n')
        self.stream.write(dot_line)
        self.stream.write('\n')
        self.stream.write('\n')

    def _print_ref_(self, name):
        self.stream.write(".. _api_{0}_{1}:\n\n".format("_".join(
Z
Zeng Jinle 已提交
169
            self.module_prefix.split(".")), name))
W
Wang,Jeff 已提交
170

M
MRXLT 已提交
171 172 173

def generate_doc(module_name, module_prefix, output, output_name,
                 to_multiple_files, output_dir):
Z
Zeng Jinle 已提交
174 175 176 177 178 179
    if module_name == "":
        module_name = None

    if module_prefix == "":
        module_prefix = None

D
dongdaxiang 已提交
180 181 182 183 184
    print("module_name: {}".format(module_name))
    print("module_prefix: {}".format(module_prefix))
    print("output: {}".format(output))
    print("output_name: {}".format(output_name))
    print("output_dir: {}".format(output_dir))
Z
Zeng Jinle 已提交
185 186 187
    gen = DocGenerator()

    if module_name is None:
188 189
        gen.module = eval(output_name)
        gen.module_name = str(output_name)
Z
Zeng Jinle 已提交
190
    else:
D
dongdaxiang 已提交
191
        print("output name: {}".format(output_name))
192
        gen.module = eval(output_name)
Z
Zeng Jinle 已提交
193
        for each_module_name in module_name.split('.'):
D
dongdaxiang 已提交
194 195 196
            print("forloop module name: {}".format(each_module_name))
            print("module")
            print(gen.module)
Z
Zeng Jinle 已提交
197
            if not hasattr(gen.module, each_module_name):
D
dongdaxiang 已提交
198
                raise ValueError("Cannot find paddle.{0}".format(module_name))
Z
Zeng Jinle 已提交
199 200 201
            else:
                gen.module = getattr(gen.module, each_module_name)

202
        gen.module_name = output_name + "." + module_name
Z
Zeng Jinle 已提交
203 204 205 206

    if module_prefix is None:
        gen.module_prefix = gen.module_name
    else:
207
        gen.module_prefix = output_name + "." + module_prefix
Z
Zeng Jinle 已提交
208

M
MRXLT 已提交
209
    dirname = output if to_multiple_files else os.path.dirname(output)
210 211 212 213 214

    if output_dir != None:
        dirname = output_dir + "/" + dirname
        output = output_dir + "/" + output

M
MRXLT 已提交
215 216
    if len(dirname) > 0 and (not os.path.exists(dirname) or
                             not os.path.isdir(dirname)):
Z
Zeng Jinle 已提交
217 218 219 220 221 222 223 224
        os.makedirs(dirname)

    if not to_multiple_files:
        header_name = gen.module_name
        if module_prefix is not None:
            prefix_len = len(gen.module_prefix)
            assert gen.module_prefix == gen.module_name[0:prefix_len],    \
                "module_prefix must be prefix of module_name"
M
MRXLT 已提交
225
            diff_name = gen.module_name[prefix_len + 1:]
Z
Zeng Jinle 已提交
226 227 228 229 230 231 232 233 234 235 236
            if diff_name != "":
                header_name = diff_name
    else:
        header_name = None

    if not to_multiple_files:
        with gen.guard(output):
            gen.print_header_reminder()
            gen._print_header_(header_name, dot='=', is_title=True)
            gen.print_current_module()
    else:
M
MRXLT 已提交
237
        apis = sorted(gen.module.__all__, key=str.lower)
Z
Zeng Jinle 已提交
238 239 240 241
        for api in apis:
            header_name = api
            with gen.guard(os.path.join(output, api + '.rst')):
                gen.print_header_reminder()
T
tianshuo78520a 已提交
242
                gen.print_item(api, output_name)
Z
Zeng Jinle 已提交
243

W
Wang,Jeff 已提交
244 245 246

def main():
    args = parse_arg()
M
MRXLT 已提交
247 248
    generate_doc(args.module_name, args.module_prefix, args.output,
                 args.output_name, args.to_multiple_files, args.output_dir)
W
Wang,Jeff 已提交
249 250 251 252


if __name__ == '__main__':
    main()