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