/doc/summarize.py

http://github.com/numpy/numpy · Python · 172 lines · 120 code · 28 blank · 24 comment · 29 complexity · b2924df1f99d40360f0d419cb2d86d00 MD5 · raw file

  1. #!/usr/bin/env python
  2. """
  3. summarize.py
  4. Show a summary about which Numpy functions are documented and which are not.
  5. """
  6. from __future__ import division, absolute_import, print_function
  7. import os, glob, re, sys, inspect, optparse
  8. import collections
  9. sys.path.append(os.path.join(os.path.dirname(__file__), 'sphinxext'))
  10. from sphinxext.phantom_import import import_phantom_module
  11. from sphinxext.autosummary_generate import get_documented
  12. CUR_DIR = os.path.dirname(__file__)
  13. SOURCE_DIR = os.path.join(CUR_DIR, 'source', 'reference')
  14. SKIP_LIST = """
  15. # --- aliases:
  16. alltrue sometrue bitwise_not cumproduct
  17. row_stack column_stack product rank
  18. # -- skipped:
  19. core lib f2py dual doc emath ma rec char distutils oldnumeric numarray
  20. testing version matlib
  21. add_docstring add_newdoc add_newdocs fastCopyAndTranspose pkgload
  22. conjugate disp
  23. int0 object0 unicode0 uint0 string_ string0 void0
  24. flagsobj
  25. setup PackageLoader
  26. lib.scimath.arccos lib.scimath.arcsin lib.scimath.arccosh lib.scimath.arcsinh
  27. lib.scimath.arctanh lib.scimath.log lib.scimath.log2 lib.scimath.log10
  28. lib.scimath.logn lib.scimath.power lib.scimath.sqrt
  29. # --- numpy.random:
  30. random random.info random.mtrand random.ranf random.sample random.random
  31. # --- numpy.fft:
  32. fft fft.Tester fft.bench fft.fftpack fft.fftpack_lite fft.helper
  33. fft.info fft.test
  34. # --- numpy.linalg:
  35. linalg linalg.Tester
  36. linalg.bench linalg.info linalg.lapack_lite linalg.linalg linalg.test
  37. # --- numpy.ctypeslib:
  38. ctypeslib ctypeslib.test
  39. """.split()
  40. def main():
  41. p = optparse.OptionParser(__doc__)
  42. p.add_option("-c", "--columns", action="store", type="int", dest="cols",
  43. default=3, help="Maximum number of columns")
  44. options, args = p.parse_args()
  45. if len(args) != 0:
  46. p.error('Wrong number of arguments')
  47. # prepare
  48. fn = os.path.join(CUR_DIR, 'dump.xml')
  49. if os.path.isfile(fn):
  50. import_phantom_module(fn)
  51. # check
  52. documented, undocumented = check_numpy()
  53. # report
  54. in_sections = {}
  55. for name, locations in documented.items():
  56. for (filename, section, keyword, toctree) in locations:
  57. in_sections.setdefault((filename, section, keyword), []).append(name)
  58. print("Documented")
  59. print("==========\n")
  60. last_filename = None
  61. for (filename, section, keyword), names in sorted(in_sections.items()):
  62. if filename != last_filename:
  63. print("--- %s\n" % filename)
  64. last_filename = filename
  65. print(" ** ", section)
  66. print(format_in_columns(sorted(names), options.cols))
  67. print("\n")
  68. print("")
  69. print("Undocumented")
  70. print("============\n")
  71. print(format_in_columns(sorted(undocumented.keys()), options.cols))
  72. def check_numpy():
  73. documented = get_documented(glob.glob(SOURCE_DIR + '/*.rst'))
  74. undocumented = {}
  75. import numpy, numpy.fft, numpy.linalg, numpy.random
  76. for mod in [numpy, numpy.fft, numpy.linalg, numpy.random,
  77. numpy.ctypeslib, numpy.emath, numpy.ma]:
  78. undocumented.update(get_undocumented(documented, mod, skip=SKIP_LIST))
  79. for d in (documented, undocumented):
  80. for k in d.keys():
  81. if k.startswith('numpy.'):
  82. d[k[6:]] = d[k]
  83. del d[k]
  84. return documented, undocumented
  85. def get_undocumented(documented, module, module_name=None, skip=[]):
  86. """
  87. Find out which items in Numpy are not documented.
  88. Returns
  89. -------
  90. undocumented : dict of bool
  91. Dictionary containing True for each documented item name
  92. and False for each undocumented one.
  93. """
  94. undocumented = {}
  95. if module_name is None:
  96. module_name = module.__name__
  97. for name in dir(module):
  98. obj = getattr(module, name)
  99. if name.startswith('_'): continue
  100. full_name = '.'.join([module_name, name])
  101. if full_name in skip: continue
  102. if full_name.startswith('numpy.') and full_name[6:] in skip: continue
  103. if not (inspect.ismodule(obj) or isinstance(obj, collections.Callable) or inspect.isclass(obj)):
  104. continue
  105. if full_name not in documented:
  106. undocumented[full_name] = True
  107. return undocumented
  108. def format_in_columns(lst, max_columns):
  109. """
  110. Format a list containing strings to a string containing the items
  111. in columns.
  112. """
  113. lst = [str(_m) for _m in lst]
  114. col_len = max([len(_m) for _m in lst]) + 2
  115. ncols = 80//col_len
  116. if ncols > max_columns:
  117. ncols = max_columns
  118. if ncols <= 0:
  119. ncols = 1
  120. if len(lst) % ncols == 0:
  121. nrows = len(lst)//ncols
  122. else:
  123. nrows = 1 + len(lst)//ncols
  124. fmt = ' %%-%ds ' % (col_len-2)
  125. lines = []
  126. for n in range(nrows):
  127. lines.append("".join([fmt % x for x in lst[n::nrows]]))
  128. return "\n".join(lines)
  129. if __name__ == "__main__": main()