You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

check_tools.py 6.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import inspect
  2. import os
  3. import sys
  4. def _colored_string(string: str, color: str or int) -> str:
  5. """在终端中显示一串有颜色的文字
  6. :param string: 在终端中显示的文字
  7. :param color: 文字的颜色
  8. :return:
  9. """
  10. if isinstance(color, str):
  11. color = {
  12. "black": 30, "Black": 30, "BLACK": 30,
  13. "red": 31, "Red": 31, "RED": 31,
  14. "green": 32, "Green": 32, "GREEN": 32,
  15. "yellow": 33, "Yellow": 33, "YELLOW": 33,
  16. "blue": 34, "Blue": 34, "BLUE": 34,
  17. "purple": 35, "Purple": 35, "PURPLE": 35,
  18. "cyan": 36, "Cyan": 36, "CYAN": 36,
  19. "white": 37, "White": 37, "WHITE": 37
  20. }[color]
  21. return "\033[%dm%s\033[0m" % (color, string)
  22. def gr(string, flag):
  23. if flag:
  24. return _colored_string(string, "green")
  25. else:
  26. return _colored_string(string, "red")
  27. def find_all_modules():
  28. modules = {}
  29. children = {}
  30. to_doc = set()
  31. root = '../fastNLP'
  32. for path, dirs, files in os.walk(root):
  33. for file in files:
  34. if file.endswith('.py'):
  35. name = ".".join(path.split('/')[1:])
  36. if file.split('.')[0] != "__init__":
  37. name = name + '.' + file.split('.')[0]
  38. __import__(name)
  39. m = sys.modules[name]
  40. modules[name] = m
  41. try:
  42. m.__all__
  43. except:
  44. print(name, "__all__ missing")
  45. continue
  46. if m.__doc__ is None:
  47. print(name, "__doc__ missing")
  48. continue
  49. if "undocumented" not in m.__doc__:
  50. to_doc.add(name)
  51. for module in to_doc:
  52. t = ".".join(module.split('.')[:-1])
  53. if t in to_doc:
  54. if t not in children:
  55. children[t] = set()
  56. children[t].add(module)
  57. for m in children:
  58. children[m] = sorted(children[m])
  59. return modules, to_doc, children
  60. def create_rst_file(modules, name, children):
  61. m = modules[name]
  62. with open("./source/" + name + ".rst", "w") as fout:
  63. t = "=" * len(name)
  64. fout.write(name + "\n")
  65. fout.write(t + "\n")
  66. fout.write("\n")
  67. fout.write(".. automodule:: " + name + "\n")
  68. if name != "fastNLP.core" and len(m.__all__) > 0:
  69. fout.write(" :members: " + ", ".join(m.__all__) + "\n")
  70. short = name[len("fastNLP."):]
  71. if not (short.startswith('models') or short.startswith('modules') or short.startswith('embeddings')):
  72. fout.write(" :inherited-members:\n")
  73. fout.write("\n")
  74. if name in children:
  75. fout.write("子模块\n------\n\n.. toctree::\n :maxdepth: 1\n\n")
  76. for module in children[name]:
  77. fout.write(" " + module + "\n")
  78. def check_file(m, name):
  79. names = name.split('.')
  80. test_name = "test." + ".".join(names[1:-1]) + ".test_" + names[-1]
  81. try:
  82. __import__(test_name)
  83. tm = sys.modules[test_name]
  84. except ModuleNotFoundError:
  85. tm = None
  86. tested = tm is not None
  87. funcs = {}
  88. classes = {}
  89. for item, obj in inspect.getmembers(m):
  90. if inspect.isclass(obj) and obj.__module__ == name and not obj.__name__.startswith('_'):
  91. this = (obj.__doc__ is not None, tested and obj.__name__ in dir(tm), {})
  92. for i in dir(obj):
  93. func = getattr(obj, i)
  94. if inspect.isfunction(func) and not i.startswith('_'):
  95. this[2][i] = (func.__doc__ is not None, False)
  96. classes[obj.__name__] = this
  97. if inspect.isfunction(obj) and obj.__module__ == name and not obj.__name__.startswith('_'):
  98. this = (obj.__doc__ is not None, tested and obj.__name__ in dir(tm)) # docs
  99. funcs[obj.__name__] = this
  100. return funcs, classes
  101. def check_files(modules, out=None):
  102. for name in sorted(modules.keys()):
  103. print(name, file=out)
  104. funcs, classes = check_file(modules[name], name)
  105. if out is None:
  106. for f in funcs:
  107. print("%-30s \t %s \t %s" % (f, gr("文档", funcs[f][0]), gr("测试", funcs[f][1])))
  108. for c in classes:
  109. print("%-30s \t %s \t %s" % (c, gr("文档", classes[c][0]), gr("测试", classes[c][1])))
  110. methods = classes[c][2]
  111. for f in methods:
  112. print(" %-28s \t %s" % (f, gr("文档", methods[f][0])))
  113. else:
  114. for f in funcs:
  115. if not funcs[f][0]:
  116. print("缺少文档 %s" % (f), file=out)
  117. if not funcs[f][1]:
  118. print("缺少测试 %s" % (f), file=out)
  119. for c in classes:
  120. if not classes[c][0]:
  121. print("缺少文档 %s" % (c), file=out)
  122. if not classes[c][1]:
  123. print("缺少测试 %s" % (c), file=out)
  124. methods = classes[c][2]
  125. for f in methods:
  126. if not methods[f][0]:
  127. print("缺少文档 %s" % (c + "." + f), file=out)
  128. print(file=out)
  129. def main_check():
  130. sys.path.append("..")
  131. print(_colored_string('Getting modules...', "Blue"))
  132. modules, to_doc, children = find_all_modules()
  133. print(_colored_string('Done!', "Green"))
  134. print(_colored_string('Creating rst files...', "Blue"))
  135. for name in to_doc:
  136. create_rst_file(modules, name, children)
  137. print(_colored_string('Done!', "Green"))
  138. print(_colored_string('Checking all files...', "Blue"))
  139. check_files(modules, out=open("results.txt", "w"))
  140. print(_colored_string('Done!', "Green"))
  141. def check_file_r(file_path):
  142. with open(file_path) as fin:
  143. content = fin.read()
  144. index = -3
  145. cuts = []
  146. while index != -1:
  147. index = content.find('"""',index+3)
  148. cuts.append(index)
  149. cuts = cuts[:-1]
  150. assert len(cuts)%2 == 0
  151. write_content = ""
  152. last = 0
  153. for i in range(len(cuts)//2):
  154. start, end = cuts[i+i], cuts[i+i+1]
  155. if content[start-1] == "r":
  156. write_content += content[last:end+3]
  157. else:
  158. write_content += content[last:start] + "r"
  159. write_content += content[start:end+3]
  160. last = end + 3
  161. write_content += content[last:]
  162. with open(file_path, "w") as fout:
  163. fout.write(write_content)
  164. def add_r(base_path='../fastNLP'):
  165. for path, _, files in os.walk(base_path):
  166. for f in files:
  167. if f.endswith(".py"):
  168. check_file_r(os.path.abspath(os.path.join(path,f)))
  169. # sys.exit(0)
  170. if __name__ == "__main__":
  171. add_r()