-
Notifications
You must be signed in to change notification settings - Fork 56
/
checkDocs.py
executable file
·102 lines (88 loc) · 2.75 KB
/
checkDocs.py
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
96
97
98
99
100
101
102
#!/usr/bin/env python3
import os.path, importlib, pkgutil, sys
import pygsti
from pprint import pprint
from collections import defaultdict
from inspect import *
import inspect
def fullname(o):
try:
if o.__module__ is None:
mod = ''
else:
mod = o.__module__
return mod + "." + o.__name__ #o.__class__.__name__
except AttributeError:
return ''
def parse_doc_arg_set(doc):
args = set()
if 'Parameters' not in doc or \
'Returns' not in doc:
raise ValueError('Docstring malformed')
desc, rest = doc.split('Parameters')
params, returns = rest.split('Returns')
for line in params.split('\n'):
if ':' in line:
arg = line.split(':')[0].strip()
if ',' in arg:
inner_args = set(map(lambda s : s.strip(), arg.split(',')))
else:
inner_args = {arg}
for arg in inner_args:
if ' ' not in arg and \
'`' not in arg:
args.add(arg)
return args
found = defaultdict(set)
data = defaultdict(dict)
def mark(item, k):
found[k].add(fullname(item))
def check_args_in_docstring(item):
args, _, kwargs, _ = getargspec(item)
if kwargs is None or kwargs in ['kwargs', 'kwds']:
kwargs = []
argset = set(args)
if 'self' in argset:
argset.remove('self')
for arg in args + [k for k, v in kwargs]:
if item.__doc__ is None:
mark(item, 'missing')
else:
if arg not in item.__doc__:
mark(item, 'incomplete')
try:
docargs = parse_doc_arg_set(item.__doc__)
extraargs = set.difference(argset, docargs)
if len(extraargs) > 0:
mark(item, 'incomplete')
data['incomplete'][fullname(item)] = extraargs
except ValueError:
mark(item, 'malformed')
def check_function(f):
#print('Checking function {}'.format(f.__name__))
check_args_in_docstring(f)
def check_class(c):
check(c)
def check_method(m):
check_args_in_docstring(m)
def check(module):
for member in getmembers(module):
name, member = member
if 'pygsti' in fullname(member):
if isfunction(member):
check_function(member)
if ismethod(member):
check_method(member)
if isclass(member):
check_class(member)
if ismodule(member):
check(member)
def main(args):
check(pygsti)
for k, v in found.items():
print('{}:'.format(k))
print(' ' + '\n '.join(v))
#pprint(data)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))