PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/tool/getdocstrings.py

https://bitbucket.org/bwesterb/pypy
Python | 99 lines | 73 code | 21 blank | 5 comment | 15 complexity | ba73eb0047b3f64ccea806948e7315c3 MD5 | raw file
  1. import re
  2. from os import listdir
  3. from sys import stdin, stdout, stderr
  4. from pypy.conftest import pypydir
  5. where = pypydir + '/objspace/std/'
  6. quote = '(' + "'" + '|' + '"' + ')'
  7. triplequotes = '(' + "'''" + '|' + '"""' + ')'
  8. # Note: this will produce erroneous result if you nest triple quotes
  9. # in your docstring.
  10. def mk_std_filelist():
  11. ''' go to pypy/objs/std and get all the *type.py files, except for
  12. typetype.py which has to be patched by hand.'''
  13. filelist = []
  14. filenames = listdir(where)
  15. for f in filenames:
  16. if f.endswith('type.py'):
  17. if f != 'typetype.py':
  18. filelist.append(f)
  19. return filelist
  20. def compile_doc():
  21. return re.compile(r"__doc__\s+=\s+" + triplequotes +
  22. r"(?P<docstring>.*)"+ triplequotes ,
  23. re.DOTALL
  24. )
  25. def compile_typedef(typ):
  26. return re.compile(r"(?P<whitespace>\s+)"
  27. + r"(?P<typeassign>" + typ
  28. + "_typedef = StdTypeDef+\s*\(\s*"
  29. + quote + typ + quote + ",).*"
  30. + r"(?P<indent>^\s+)"
  31. + r"(?P<newassign>__new__\s*=\s*newmethod)",
  32. re.DOTALL | re.MULTILINE)
  33. def get_pypydoc(sourcefile):
  34. doc = compile_doc()
  35. try: # if this works we already have a docstring
  36. pypydoc = doc.search(sourcefile).group('docstring')
  37. except AttributeError: # No pypy docstring
  38. return None
  39. return pypydoc
  40. def get_cpydoc(typ):
  41. # relies on being run by CPython.
  42. try:
  43. cpydoc = eval(typ + '.__doc__')
  44. except NameError: # No CPython docstring
  45. cpydoc = None
  46. return cpydoc
  47. def add_docstring(typ, sourcefile):
  48. pypydoc = get_pypydoc(sourcefile)
  49. cpydoc = get_cpydoc(typ)
  50. if pypydoc:
  51. stderr.write('%s: already has a pypy docstring\n' % typ)
  52. return None
  53. elif not cpydoc:
  54. stderr.write('%s: does not have a cpython docstring\n' % typ)
  55. return None
  56. else:
  57. docstring="__doc__ = '''" + cpydoc + "''',"
  58. typedef = compile_typedef(typ)
  59. newsearch = typedef.search(sourcefile)
  60. if not newsearch:
  61. stderr.write('%s: has a cpython docstring, but no __new__, to determine where to put it.\n' % typ)
  62. return None
  63. else:
  64. return re.sub(newsearch.group('indent') +
  65. newsearch.group('newassign'),
  66. newsearch.group('indent') +
  67. docstring + '\n' +
  68. newsearch.group('indent') +
  69. newsearch.group('newassign'),
  70. sourcefile)
  71. if __name__ == '__main__':
  72. filenames = mk_std_filelist()
  73. for f in filenames:
  74. inf = file(where + f).read()
  75. outs = add_docstring(f[:-7], inf)
  76. if outs is not None:
  77. outf = file(where + f, 'w')
  78. outf.write(outs)