File: getdocstrings.py

package info (click to toggle)
pypy3 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 111,848 kB
  • sloc: python: 1,291,746; ansic: 74,281; asm: 5,187; cpp: 3,017; sh: 2,533; makefile: 544; xml: 243; lisp: 45; csh: 21; awk: 4
file content (95 lines) | stat: -rw-r--r-- 2,954 bytes parent folder | download | duplicates (9)
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)