OpenAttack

Форк
0
/
build-doc.py 
300 строк · 10.8 Кб
1
import os
2
import OpenAttack
3

4
def getSubClasses(module, clss):
5
    ret = []
6
    for name in dir(module):
7
        try:
8
            if issubclass(module.__dict__[name], clss):
9
                ret.append(name)
10
        except TypeError:
11
            continue
12
    return ret
13

14
def getDocMembers(clss):
15
    ret = []
16
    for kw in dir(clss):
17
        if kw.startswith("_"):
18
            continue
19
        if clss.__dict__[kw].__doc__ is not None:
20
            ret.append(kw)
21
    return ret
22

23
def make_attacker(path):
24
    addition_members = {
25
        "UATAttacker": ["get_triggers"],
26
    }
27
    opt = "===================\nAttackers API\n===================\n\n"
28

29
    opt += "Attacker\n=============\n\n.. autoclass:: OpenAttack.Attacker\n    :members:\n\n"
30
    opt += "-" * 36 + "\n\n"
31
    
32
    opt += "ClassificationAttacker\n==============================\n\n.. autoclass:: OpenAttack.attackers.ClassificationAttacker\n    :members:\n\n"
33
    opt += "-" * 36 + "\n\n"
34
    
35
    
36
    for name in getSubClasses(OpenAttack.attackers, OpenAttack.ClassificationAttacker):
37
        if name == "ClassificationAttacker":
38
            continue
39
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
40
        opt += ".. autoclass:: OpenAttack.attackers.%s(OpenAttack.attackers.ClassificationAttacker)\n" % name
41

42
        members = ["__init__"] + (addition_members[name] if name in addition_members else [])
43
        opt += "    :members: " + (", ".join(members)) + "\n\n"
44
    open(path, "w", encoding="utf-8").write(opt)
45
    return opt
46

47
def make_attack_eval(path):
48
    opt = "========================\nAttackEvals API\n========================\n\n"
49
    opt += "AttackEval\n----------------\n\n.. autoclass:: OpenAttack.AttackEval\n    :members: __init__, eval, ieval\n\n"
50
    open(path, "w", encoding="utf-8").write(opt)
51

52
def make_victim(path):
53
    addition_members = {
54
        "TransformersClassifier": ["to"],
55
    }
56
    skip_list = {"Classifier"}
57

58
    opt = "===================\nVictims API\n===================\n\n"
59
    opt += "Classifier\n===========================\n\n.. autoclass:: OpenAttack.victim.classifiers.Classifier\n    :members:\n\n"
60
    opt += "-" * 36 + "\n\n"
61
    
62
    for name in getSubClasses(OpenAttack.victim.classifiers, OpenAttack.victim.classifiers.Classifier):
63
        if name in skip_list:
64
            continue
65

66
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
67
        opt += ".. autoclass:: OpenAttack.classifiers.%s(OpenAttack.Classifier)\n" % name
68

69
        members = ["__init__"] + (addition_members[name] if name in addition_members else [])
70
        opt += "    :members: " + (", ".join(members)) + "\n\n"
71
    open(path, "w", encoding="utf-8").write(opt)
72
    return opt
73
    
74
def make_data_manager(path):
75
    opt = "===================\nDataManager API\n===================\n\n.. autoclass:: OpenAttack.DataManager\n    :members:"
76
    open(path, "w", encoding="utf-8").write(opt)
77
    return opt
78

79
def make_data(path):
80
    import pkgutil
81
    cats = {
82

83
    }
84
    for data in pkgutil.iter_modules(OpenAttack.data.__path__):
85
        data = data.module_finder.find_loader(data.name)[0].load_module()
86
        if hasattr(data, "NAME") and (data.NAME in OpenAttack.DataManager.AVAILABLE_DATAS):
87
            name = data.NAME
88
            if name == "test":
89
                continue
90
            cat = name.split(".")
91
            if len(cat) == 1:
92
                continue
93
            name = ".".join(cat[1:])
94
            cat = cat[0]
95
            pack = data.__name__
96

97
            if cat not in cats:
98
                cats[cat] = []
99
            cats[cat].append({
100
                "name": name,
101
                "package":  pack
102
            })
103
    
104

105
    
106
    for cat in cats.keys():
107
        opt = "=====================\n%s\n=====================\n\n" % cat
108
        opt += ".. _label-data-%s:\n\n" % cat
109
        for data in cats[cat]:
110
            opt += data["name"] + "\n" + ("-" * (2 + len(data["name"]))) + "\n\n"
111
            opt += ".. py:data:: " + cat + "." + data["name"] + "\n\n"
112
            opt += "    .. automodule:: OpenAttack.data." + data["package"] + "\n\n"
113
        open(os.path.join(path, cat + ".rst"), "w", encoding="utf-8").write(opt)
114
    return opt
115

116
def make_metric(path):
117
    opt = "==================\nMetric API\n==================\n\n"
118
    
119

120
    metrics = []
121
    selector = []
122
    for name in dir(OpenAttack.metric):
123
        if isinstance(OpenAttack.metric.__dict__[name], type):
124
            if issubclass(OpenAttack.metric.__dict__[name], OpenAttack.metric.AttackMetric):
125
                if name == "AttackMetric":
126
                    continue
127
                metrics.append(name)
128
            elif issubclass(OpenAttack.metric.__dict__[name], OpenAttack.metric.MetricSelector):
129
                if name == "MetricSelector":
130
                    continue
131
                selector.append(name)
132
    
133
    opt += """Attacker Metrics
134
==================
135

136
.. autoclass:: OpenAttack.metric.AttackMetric
137
    :members:
138

139

140
"""
141

142
    for name in metrics:
143
        cls = OpenAttack.metric.__dict__[name]
144
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
145
        opt += ".. autoclass:: OpenAttack.metric." + name + "\n"
146
        if hasattr(cls, "calc_score"):
147
            opt += "    :members: __init__, calc_score" + "\n"
148
        else:
149
            opt += "    :members: __init__" + "\n"
150
        opt += "    :exclude-members: TAGS" + "\n\n"
151
    
152
    opt += """Metrics Selector
153
=======================
154

155
.. autoclass:: OpenAttack.metric.MetricSelector
156
    :members:
157

158

159
"""
160
    
161
    for name in selector:
162
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
163
        opt += ".. autoclass:: OpenAttack.metric." + name + "\n"
164
        opt += "    :members: " + "\n"
165
        opt += "    :exclude-members: TAGS" + "\n\n"
166
    
167
    open(path, "w", encoding="utf-8").write(opt)
168
    return opt
169

170
def make_substitute(path):
171
    opt = "======================\nSubstitutes API\n======================\n\n"
172
    opt += """
173

174
Abstract Classes
175
------------------------
176

177
.. autoclass:: OpenAttack.attack_assist.substitute.word.WordSubstitute
178
    :members: __call__
179

180
.. autoclass:: OpenAttack.attack_assist.substitute.char.CharSubstitute
181
    :members: __call__
182

183
-------------------------------------------------------------------------------
184

185

186
"""
187
    subs = getSubClasses(OpenAttack.attack_assist.substitute.word, OpenAttack.attack_assist.substitute.word.WordSubstitute)
188
    embed_based_idx = subs.index("EmbedBasedSubstitute")
189
    if embed_based_idx != -1:
190
        subs[0], subs[embed_based_idx] = subs[embed_based_idx], subs[0]
191
    
192
    for name in subs:
193
        cls = OpenAttack.attack_assist.substitute.word.__dict__[name]
194
        if cls is OpenAttack.attack_assist.substitute.word.WordSubstitute:
195
            continue
196
        
197
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
198
        opt += ".. autoclass:: OpenAttack.attack_assist.substitute.word.%s(OpenAttack.attack_assist.substitute.word.WordSubstitute)\n" % name
199
        opt += "    :members: __init__\n\n"
200

201
    subs = getSubClasses(OpenAttack.attack_assist.substitute.char, OpenAttack.attack_assist.substitute.char.CharSubstitute)
202
    
203
    for name in subs:
204
        cls = OpenAttack.attack_assist.substitute.char.__dict__[name]
205
        if cls is OpenAttack.attack_assist.substitute.char.CharSubstitute:
206
            continue
207
        
208
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
209
        opt += ".. autoclass:: OpenAttack.attack_assist.substitute.char.%s(OpenAttack.attack_assist.substitute.char.CharSubstitute)\n" % name
210
        opt += "    :members: __init__\n\n"
211

212
    open(path, "w", encoding="utf-8").write(opt)
213
    return opt
214

215
def make_text_processor(path):
216
    opt = "========================\nText Processors API\n========================\n\n"
217
    opt += "Tokenizers\n============================\n\n"
218
    opt += """
219
.. autoclass:: OpenAttack.text_process.tokenizer.Tokenizer
220
    :members: tokenize, detokenize
221

222
"""
223

224
    import OpenAttack.text_process.tokenizer
225
    
226
    for name in getSubClasses(OpenAttack.text_process.tokenizer, OpenAttack.text_process.tokenizer.Tokenizer):
227
        if name == "Tokenizer":
228
            continue
229
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
230
        opt += ".. autoclass:: OpenAttack.text_process.tokenizer.%s(OpenAttack.text_process.tokenizer.Tokenizer)\n" % name
231
        opt += "    :members:\n\n"
232
    
233
    
234
    import OpenAttack.text_process.lemmatizer
235
    
236
    opt += "Lemmatizer\n============================\n\n"
237
    opt += """
238
.. autoclass:: OpenAttack.text_process.lemmatizer.Lemmatizer
239
    :members: lemmatize, delemmatize
240

241
"""
242
    for name in getSubClasses(OpenAttack.text_process.lemmatizer, OpenAttack.text_process.lemmatizer.Lemmatizer):
243
        if name == "Lemmatizer":
244
            continue
245
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
246
        opt += ".. autoclass:: OpenAttack.text_process.lemmatizer.%s(OpenAttack.text_process.lemmatizer.Lemmatizer)\n" % name
247
        opt += "    :members:\n\n"
248

249
    
250
    import OpenAttack.text_process.constituency_parser
251
    
252
    opt += "ConstituencyParser\n============================\n\n"
253
    opt += """
254
.. autoclass:: OpenAttack.text_process.constituency_parser.ConstituencyParser
255
    :members: __call__
256

257
"""
258
    for name in getSubClasses(OpenAttack.text_process.constituency_parser, OpenAttack.text_process.constituency_parser.ConstituencyParser):
259
        if name == "ConstituencyParser":
260
            continue
261
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
262
        opt += ".. autoclass:: OpenAttack.text_process.constituency_parser.%s(OpenAttack.text_process.constituency_parser.ConstituencyParser)\n" % name
263
        opt += "    :members:\n\n"
264
    
265

266
    open(path, "w", encoding="utf-8").write(opt)
267
    return opt
268

269
def make_utils(path):
270
    opt = "=====================\nutils API\n=====================\n\n"
271
    for name in OpenAttack.utils.__dir__():
272
        if name.startswith("__"):
273
            continue
274
        obj = OpenAttack.utils.__dict__[name]
275
        if type(obj).__name__ == "module":
276
            continue
277
        opt += name + "\n" + ("-" * (2 + len(name))) + "\n\n"
278
        if type(obj).__name__  == "function":
279
            opt += ".. autofunction:: OpenAttack.utils." + name + "\n\n"
280
        else:
281
            opt += ".. autoclass:: OpenAttack.utils." + name + "\n"
282
            opt += "    :members: " + "\n\n"
283
    open(path, "w", encoding="utf-8").write(opt)
284
    return opt
285

286
def main(path):
287
    make_attacker(os.path.join(path, "attacker.rst"))
288
    make_attack_eval(os.path.join(path, "attack_eval.rst"))
289
    make_victim(os.path.join(path, "victim.rst"))
290
    make_data_manager(os.path.join(path, "data_manager.rst"))
291
    make_data(os.path.join(path, "..", "data"))
292
    make_metric(os.path.join(path, "metric.rst"))
293
    make_substitute(os.path.join(path, "substitute.rst"))
294
    make_text_processor(os.path.join(path, "text_processor.rst"))
295
    make_utils(os.path.join(path, "utils.rst"))
296

297
if __name__ == "__main__":
298
    import sys
299
    path = os.path.abspath(sys.argv[1])
300
    main(path)

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.